diff --git a/.gitignore b/.gitignore index 8cc5a84db98c18..8abcf6a88691db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ -_site -node_modules +*.sublime-workspace .DS_Store +dist/ +node_modules +npm-debug.log diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 146266d9e18cb1..00000000000000 --- a/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -examples/ -test/ -lib/ -.DS_Store diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 20fd86b6a5bee3..00000000000000 --- a/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - 0.10 diff --git a/API.md b/API.md new file mode 100644 index 00000000000000..1346c78f360b56 --- /dev/null +++ b/API.md @@ -0,0 +1,1440 @@ +# D3 API Reference + +D3 is a [collection of modules](https://github.com/d3) that are designed to work together; you can use the modules independently, or you can use them together as part of the default build. The source and documentation for each module is available in its repository. Follow the links below to learn more. For changes between major versions, see [CHANGES](https://github.com/d3/d3/blob/master/CHANGES.md); see also the [release notes](https://github.com/d3/d3/releases) and the [3.x reference](https://github.com/d3/d3-3.x-api-reference/blob/master/API-Reference.md). + +* [Arrays](#arrays-d3-array) ([Statistics](#statistics), [Search](#search), [Iterables](#iterables), [Sets](#sets), [Transformations](#transformations), [Histograms](#histograms), [Interning](#interning)) +* [Axes](#axes-d3-axis) +* [Brushes](#brushes-d3-brush) +* [Chords](#chords-d3-chord) +* [Colors](#colors-d3-color) +* [Color Schemes](#color-schemes-d3-scale-chromatic) +* [Contours](#contours-d3-contour) +* [Voronoi Diagrams](#voronoi-diagrams-d3-delaunay) +* [Dispatches](#dispatches-d3-dispatch) +* [Dragging](#dragging-d3-drag) +* [Delimiter-Separated Values](#delimiter-separated-values-d3-dsv) +* [Easings](#easings-d3-ease) +* [Fetches](#fetches-d3-fetch) +* [Forces](#forces-d3-force) +* [Number Formats](#number-formats-d3-format) +* [Geographies](#geographies-d3-geo) ([Paths](#paths), [Projections](#projections), [Spherical Math](#spherical-math), [Spherical Shapes](#spherical-shapes), [Streams](#streams), [Transforms](#transforms)) +* [Hierarchies](#hierarchies-d3-hierarchy) +* [Interpolators](#interpolators-d3-interpolate) +* [Paths](#paths-d3-path) +* [Polygons](#polygons-d3-polygon) +* [Quadtrees](#quadtrees-d3-quadtree) +* [Random Numbers](#random-numbers-d3-random) +* [Scales](#scales-d3-scale) ([Continuous](#continuous-scales), [Sequential](#sequential-scales), [Diverging](#diverging-scales), [Quantize](#quantize-scales), [Ordinal](#ordinal-scales)) +* [Selections](#selections-d3-selection) ([Selecting](#selecting-elements), [Modifying](#modifying-elements), [Data](#joining-data), [Events](#handling-events), [Control](#control-flow), [Local Variables](#local-variables), [Namespaces](#namespaces)) +* [Shapes](#shapes-d3-shape) ([Arcs](#arcs), [Pies](#pies), [Lines](#lines), [Areas](#areas), [Curves](#curves), [Links](#links), [Symbols](#symbols), [Stacks](#stacks)) +* [Time Formats](#time-formats-d3-time-format) +* [Time Intervals](#time-intervals-d3-time) +* [Timers](#timers-d3-timer) +* [Transitions](#transitions-d3-transition) +* [Zooming](#zooming-d3-zoom) + +D3 uses [semantic versioning](http://semver.org/). The current version is exposed as d3.version. + +## [Arrays (d3-array)](https://github.com/d3/d3-array/tree/v2.12.1) + +Array manipulation, ordering, searching, summarizing, etc. + +### [Statistics](https://github.com/d3/d3-array/blob/v2.12.1/README.md#statistics) + +Methods for computing basic summary statistics. + +* [d3.min](https://github.com/d3/d3-array/blob/v2.12.1/README.md#min) - compute the minimum value in an iterable. +* [d3.minIndex](https://github.com/d3/d3-array/blob/v2.12.1/README.md#minIndex) - compute the index of the minimum value in an iterable. +* [d3.max](https://github.com/d3/d3-array/blob/v2.12.1/README.md#max) - compute the maximum value in an iterable. +* [d3.maxIndex](https://github.com/d3/d3-array/blob/v2.12.1/README.md#maxIndex) - compute the index of the maximum value in an iterable. +* [d3.extent](https://github.com/d3/d3-array/blob/v2.12.1/README.md#extent) - compute the minimum and maximum value in an iterable. +* [d3.sum](https://github.com/d3/d3-array/blob/v2.12.1/README.md#sum) - compute the sum of an iterable of numbers. +* [d3.mean](https://github.com/d3/d3-array/blob/v2.12.1/README.md#mean) - compute the arithmetic mean of an iterable of numbers. +* [d3.median](https://github.com/d3/d3-array/blob/v2.12.1/README.md#median) - compute the median of an iterable of numbers (the 0.5-quantile). +* [d3.cumsum](https://github.com/d3/d3-array/blob/v2.12.1/README.md#cumsum) - compute the cumulative sum of an iterable. +* [d3.quantile](https://github.com/d3/d3-array/blob/v2.12.1/README.md#quantile) - compute a quantile for an iterable of numbers. +* [d3.quantileSorted](https://github.com/d3/d3-array/blob/v2.12.1/README.md#quantileSorted) - compute a quantile for a sorted array of numbers. +* [d3.variance](https://github.com/d3/d3-array/blob/v2.12.1/README.md#variance) - compute the variance of an iterable of numbers. +* [d3.deviation](https://github.com/d3/d3-array/blob/v2.12.1/README.md#deviation) - compute the standard deviation of an iterable of numbers. +* [d3.fcumsum](https://github.com/d3/d3-array/blob/v2.12.1/README.md#fcumsum) - compute a full precision cumulative summation of numbers. +* [d3.fsum](https://github.com/d3/d3-array/blob/v2.12.1/README.md#fsum) - compute a full precision summation of an iterable of numbers. +* [new d3.Adder](https://github.com/d3/d3-array/blob/v2.12.1/README.md#adder) - creates a full precision adder. +* [*adder*.add](https://github.com/d3/d3-array/blob/v2.12.1/README.md#adder_add) - add a value to an adder. +* [*adder*.valueOf](https://github.com/d3/d3-array/blob/v2.12.1/README.md#adder_valueOf) - returns a double precision representation of an adder’s value. + +### [Search](https://github.com/d3/d3-array/blob/v2.12.1/README.md#search) + +Methods for searching arrays for a specific element. + +* [d3.least](https://github.com/d3/d3-array/blob/v2.12.1/README.md#least) - returns the least element of an iterable. +* [d3.leastIndex](https://github.com/d3/d3-array/blob/v2.12.1/README.md#leastIndex) - returns the index of the least element of an iterable. +* [d3.greatest](https://github.com/d3/d3-array/blob/v2.12.1/README.md#greatest) - returns the greatest element of an iterable. +* [d3.greatestIndex](https://github.com/d3/d3-array/blob/v2.12.1/README.md#greatestIndex) - returns the index of the greatest element of an iterable. +* [d3.bisectCenter](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bisectCenter) - binary search for a value in a sorted array. +* [d3.bisectLeft](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bisectLeft) - binary search for a value in a sorted array. +* [d3.bisect](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bisect) - binary search for a value in a sorted array. +* [d3.bisectRight](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bisectRight) - binary search for a value in a sorted array. +* [d3.bisector](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bisector) - bisect using an accessor or comparator. +* [*bisector*.center](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bisector_center) - binary search for a value in a sorted array. +* [*bisector*.left](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bisector_left) - bisectLeft, with the given comparator. +* [*bisector*.right](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bisector_right) - bisectRight, with the given comparator. +* [d3.quickselect](https://github.com/d3/d3-array/blob/v2.12.1/README.md#quickselect) - reorder an array of numbers. +* [d3.ascending](https://github.com/d3/d3-array/blob/v2.12.1/README.md#ascending) - compute the natural order of two values. +* [d3.descending](https://github.com/d3/d3-array/blob/v2.12.1/README.md#descending) - compute the natural order of two values. + +### [Transformations](https://github.com/d3/d3-array/blob/v2.12.1/README.md#transformations) + +Methods for transforming arrays and for generating new arrays. + +* [d3.group](https://github.com/d3/d3-array/blob/v2.12.1/README.md#group) - group an iterable into a nested Map. +* [d3.groups](https://github.com/d3/d3-array/blob/v2.12.1/README.md#groups) - group an iterable into a nested array. +* [d3.index](https://github.com/d3/d3-array/blob/v2.12.1/README.md#index) - index an iterable into a nested Map. +* [d3.indexes](https://github.com/d3/d3-array/blob/v2.12.1/README.md#indexes) - index an iterable into a nested array. +* [d3.rollup](https://github.com/d3/d3-array/blob/v2.12.1/README.md#rollup) - reduce an iterable into a nested Map. +* [d3.rollups](https://github.com/d3/d3-array/blob/v2.12.1/README.md#rollups) - reduce an iterable into a nested array. +* [d3.groupSort](https://github.com/d3/d3-array/blob/v2.12.1/README.md#groupSort) - sort keys according to grouped values. +* [d3.count](https://github.com/d3/d3-array/blob/v2.12.1/README.md#count) - count valid number values in an iterable. +* [d3.cross](https://github.com/d3/d3-array/blob/v2.12.1/README.md#cross) - compute the Cartesian product of two iterables. +* [d3.merge](https://github.com/d3/d3-array/blob/v2.12.1/README.md#merge) - merge multiple iterables into one array. +* [d3.pairs](https://github.com/d3/d3-array/blob/v2.12.1/README.md#pairs) - create an array of adjacent pairs of elements. +* [d3.permute](https://github.com/d3/d3-array/blob/v2.12.1/README.md#permute) - reorder an iterable of elements according to an iterable of indexes. +* [d3.shuffle](https://github.com/d3/d3-array/blob/v2.12.1/README.md#shuffle) - randomize the order of an iterable. +* [d3.shuffler](https://github.com/d3/d3-array/blob/v2.12.1/README.md#shuffler) - randomize the order of an iterable. +* [d3.ticks](https://github.com/d3/d3-array/blob/v2.12.1/README.md#ticks) - generate representative values from a numeric interval. +* [d3.tickIncrement](https://github.com/d3/d3-array/blob/v2.12.1/README.md#tickIncrement) - generate representative values from a numeric interval. +* [d3.tickStep](https://github.com/d3/d3-array/blob/v2.12.1/README.md#tickStep) - generate representative values from a numeric interval. +* [d3.nice](https://github.com/d3/d3-array/blob/v2.12.1/README.md#nice) - extend an interval to align with ticks. +* [d3.range](https://github.com/d3/d3-array/blob/v2.12.1/README.md#range) - generate a range of numeric values. +* [d3.transpose](https://github.com/d3/d3-array/blob/v2.12.1/README.md#transpose) - transpose an array of arrays. +* [d3.zip](https://github.com/d3/d3-array/blob/v2.12.1/README.md#zip) - transpose a variable number of arrays. + +### [Iterables](https://github.com/d3/d3-array/blob/v2.12.1/README.md#iterables) + +* [d3.every](https://github.com/d3/d3-array/blob/v2.12.1/README.md#every) - test if all values satisfy a condition. +* [d3.some](https://github.com/d3/d3-array/blob/v2.12.1/README.md#some) - test if any value satisfies a condition. +* [d3.filter](https://github.com/d3/d3-array/blob/v2.12.1/README.md#filter) - filter values. +* [d3.map](https://github.com/d3/d3-array/blob/v2.12.1/README.md#map) - map values. +* [d3.reduce](https://github.com/d3/d3-array/blob/v2.12.1/README.md#reduce) - reduce values. +* [d3.reverse](https://github.com/d3/d3-array/blob/v2.12.1/README.md#reverse) - reverse the order of values. +* [d3.sort](https://github.com/d3/d3-array/blob/v2.12.1/README.md#sort) - sort values. + +### [Sets](https://github.com/d3/d3-array/blob/v2.12.1/README.md#sets) + +* [d3.difference](https://github.com/d3/d3-array/blob/v2.12.1/README.md#difference) - compute a set difference. +* [d3.disjoint](https://github.com/d3/d3-array/blob/v2.12.1/README.md#disjoint) - test whether two sets are disjoint. +* [d3.intersection](https://github.com/d3/d3-array/blob/v2.12.1/README.md#intersection) - compute a set intersection. +* [d3.superset](https://github.com/d3/d3-array/blob/v2.12.1/README.md#superset) - test whether a set is a superset of another. +* [d3.subset](https://github.com/d3/d3-array/blob/v2.12.1/README.md#subset) - test whether a set is a subset of another. +* [d3.union](https://github.com/d3/d3-array/blob/v2.12.1/README.md#union) - compute a set union. + +### [Histograms](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bins) + +Bin discrete samples into continuous, non-overlapping intervals. + +* [d3.bin](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bin) - create a new bin generator. +* [*bin*](https://github.com/d3/d3-array/blob/v2.12.1/README.md#_bin) - bins a given array of samples. +* [*bin*.value](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bin_value) - specify a value accessor for each sample. +* [*bin*.domain](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bin_domain) - specify the interval of observable values. +* [*bin*.thresholds](https://github.com/d3/d3-array/blob/v2.12.1/README.md#bin_thresholds) - specify how values are divided into bins. +* [d3.thresholdFreedmanDiaconis](https://github.com/d3/d3-array/blob/v2.12.1/README.md#thresholdFreedmanDiaconis) - the Freedman–Diaconis binning rule. +* [d3.thresholdScott](https://github.com/d3/d3-array/blob/v2.12.1/README.md#thresholdScott) - Scott’s normal reference binning rule. +* [d3.thresholdSturges](https://github.com/d3/d3-array/blob/v2.12.1/README.md#thresholdSturges) - Sturges’ binning formula. + +### [Interning](https://github.com/d3/d3-array/blob/v2.12.1/README.md#interning) + +* [d3.InternMap](https://github.com/d3/d3-array/blob/v2.12.1/README.md#InternMap) - a key-interning Map. +* [d3.InternSet](https://github.com/d3/d3-array/blob/v2.12.1/README.md#InternSet) - a value-interning Set. + +## [Axes (d3-axis)](https://github.com/d3/d3-axis/tree/v2.1.0) + +Human-readable reference marks for scales. + +* [d3.axisTop](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axisTop) - create a new top-oriented axis generator. +* [d3.axisRight](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axisRight) - create a new right-oriented axis generator. +* [d3.axisBottom](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axisBottom) - create a new bottom-oriented axis generator. +* [d3.axisLeft](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axisLeft) - create a new left-oriented axis generator. +* [*axis*](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#_axis) - generate an axis for the given selection. +* [*axis*.scale](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_scale) - set the scale. +* [*axis*.ticks](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_ticks) - customize how ticks are generated and formatted. +* [*axis*.tickArguments](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_tickArguments) - customize how ticks are generated and formatted. +* [*axis*.tickValues](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_tickValues) - set the tick values explicitly. +* [*axis*.tickFormat](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_tickFormat) - set the tick format explicitly. +* [*axis*.tickSize](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_tickSize) - set the size of the ticks. +* [*axis*.tickSizeInner](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_tickSizeInner) - set the size of inner ticks. +* [*axis*.tickSizeOuter](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_tickSizeOuter) - set the size of outer (extent) ticks. +* [*axis*.tickPadding](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_tickPadding) - set the padding between ticks and labels. +* [*axis*.offset](https://github.com/d3/d3-axis/blob/v2.1.0/README.md#axis_offset) - set the pixel offset for crisp edges. + +## [Brushes (d3-brush)](https://github.com/d3/d3-brush/tree/v2.0.0) + +Select a one- or two-dimensional region using the mouse or touch. + +* [d3.brush](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush) - create a new two-dimensional brush. +* [d3.brushX](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brushX) - create a brush along the *x*-dimension. +* [d3.brushY](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brushY) - create a brush along the *y*-dimension. +* [*brush*](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#_brush) - apply the brush to a selection. +* [*brush*.move](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush_move) - move the brush selection. +* [*brush*.clear](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush_clear) - clear the brush selection. +* [*brush*.extent](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush_extent) - define the brushable region. +* [*brush*.filter](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush_filter) - control which input events initiate brushing. +* [*brush*.touchable](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush_touchable) - set the touch support detector. +* [*brush*.keyModifiers](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush_keyModifiers) - enable or disable key interaction. +* [*brush*.handleSize](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush_handleSize) - set the size of the brush handles. +* [*brush*.on](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brush_on) - listen for brush events. +* [d3.brushSelection](https://github.com/d3/d3-brush/blob/v2.0.0/README.md#brushSelection) - get the brush selection for a given node. + +## [Chords (d3-chord)](https://github.com/d3/d3-chord/tree/v2.0.0) + +* [d3.chord](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#chord) - create a new chord layout. +* [*chord*](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#_chord) - compute the layout for the given matrix. +* [*chord*.padAngle](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#chord_padAngle) - set the padding between adjacent groups. +* [*chord*.sortGroups](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#chord_sortGroups) - define the group order. +* [*chord*.sortSubgroups](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#chord_sortSubgroups) - define the source and target order within groups. +* [*chord*.sortChords](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#chord_sortChords) - define the chord order across groups. +* [d3.chordDirected](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#chordDirected) - create a directed chord generator. +* [d3.chordTranspose](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#chordTranspose) - create a transposed chord generator. +* [d3.ribbon](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon) - create a ribbon shape generator. +* [*ribbon*](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#_ribbon) - generate a ribbon shape. +* [*ribbon*.source](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_source) - set the source accessor. +* [*ribbon*.target](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_target) - set the target accessor. +* [*ribbon*.radius](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_radius) - set the ribbon source and target radius. +* [*ribbon*.sourceRadius](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_sourceRadius) - set the ribbon source radius. +* [*ribbon*.targetRadius](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_targetRadius) - set the ribbon target radius. +* [*ribbon*.startAngle](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_startAngle) - set the ribbon source or target start angle. +* [*ribbon*.endAngle](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_endAngle) - set the ribbon source or target end angle. +* [*ribbon*.padAngle](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_padAngle) - set the pad angle accessor. +* [*ribbon*.context](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbon_context) - set the render context. +* [d3.ribbonArrow](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbonArrow) - create an arrow ribbon generator. +* [*ribbonArrow*.headRadius](https://github.com/d3/d3-chord/blob/v2.0.0/README.md#ribbonArrow_headRadius) - set the arrowhead radius accessor. + +## [Colors (d3-color)](https://github.com/d3/d3-color/tree/v2.0.0) + +Color manipulation and color space conversion. + +* [d3.color](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color) - parse the given CSS color specifier. +* [*color*.opacity](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_opacity) - the color’s opacity. +* [*color*.rgb](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_rgb) - compute the RGB equivalent of this color. +* [*color*.copy](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_copy) - return a copy of this color. +* [*color*.brighter](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_brighter) - create a brighter copy of this color. +* [*color*.darker](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_darker) - create a darker copy of this color. +* [*color*.displayable](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_displayable) - returns true if the color is displayable on standard hardware. +* [*color*.formatHex](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_formatHex) - returns the hexadecimal RGB string representation of this color. +* [*color*.formatHsl](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_formatHsl) - returns the RGB string representation of this color. +* [*color*.formatRgb](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_formatRgb) - returns the HSL string representation of this color. +* [*color*.toString](https://github.com/d3/d3-color/blob/v2.0.0/README.md#color_toString) - returns the RGB string representation of this color. +* [d3.rgb](https://github.com/d3/d3-color/blob/v2.0.0/README.md#rgb) - create a new RGB color. +* [d3.hsl](https://github.com/d3/d3-color/blob/v2.0.0/README.md#hsl) - create a new HSL color. +* [d3.lab](https://github.com/d3/d3-color/blob/v2.0.0/README.md#lab) - create a new Lab color. +* [d3.gray](https://github.com/d3/d3-color/blob/v2.0.0/README.md#gray) - create a new Lab gray. +* [d3.hcl](https://github.com/d3/d3-color/blob/v2.0.0/README.md#hcl) - create a new HCL color. +* [d3.lch](https://github.com/d3/d3-color/blob/v2.0.0/README.md#lch) - create a new HCL color. +* [d3.cubehelix](https://github.com/d3/d3-color/blob/v2.0.0/README.md#cubehelix) - create a new Cubehelix color. + +## [Color Schemes (d3-scale-chromatic)](https://github.com/d3/d3-scale-chromatic/tree/v2.0.0) + +Color ramps and palettes for quantitative, ordinal and categorical scales. + +### Categorical + +* [d3.schemeCategory10](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeCategory10) - an array of ten categorical colors. +* [d3.schemeAccent](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeAccent) - an array of eight categorical colors. +* [d3.schemeDark2](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeDark2) - an array of eight categorical colors. +* [d3.schemePaired](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePaired) - an array of twelve categorical colors. +* [d3.schemePastel1](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePastel1) - an array of nine categorical colors. +* [d3.schemePastel2](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePastel2) - an array of eight categorical colors. +* [d3.schemeSet1](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeSet1) - an array of nine categorical colors. +* [d3.schemeSet2](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeSet2) - an array of eight categorical colors. +* [d3.schemeSet3](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeSet3) - an array of twelve categorical colors. +* [d3.schemeTableau10](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeTableau10) - an array of ten categorical colors. + +### Diverging + +* [d3.interpolateBrBG](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateBrBG) - ColorBrewer BrBG interpolator. +* [d3.interpolatePiYG](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolatePiYG) - ColorBrewer PiYG interpolator. +* [d3.interpolatePRGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolatePRGn) - ColorBrewer PRGn interpolator. +* [d3.interpolatePuOr](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolatePuOr) - ColorBrewer PuOr interpolator. +* [d3.interpolateRdBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateRdBu) - ColorBrewer RdBu interpolator. +* [d3.interpolateRdGy](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateRdGy) - ColorBrewer RdGy interpolator. +* [d3.interpolateRdYlBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateRdYlBu) - ColorBrewer RdYlBu interpolator. +* [d3.interpolateRdYlGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateRdYlGn) - ColorBrewer RdYlGn interpolator. +* [d3.interpolateSpectral](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateSpectral) - ColorBrewer spectral interpolator. +* [d3.schemeBrBG](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeBrBG) - ColorBrewer BrBG scheme. +* [d3.schemePiYG](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePiYG) - ColorBrewer PiYG scheme. +* [d3.schemePRGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePRGn) - ColorBrewer PRGn scheme. +* [d3.schemePuOr](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePuOr) - ColorBrewer PuOr scheme. +* [d3.schemeRdBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeRdBu) - ColorBrewer RdBu scheme. +* [d3.schemeRdGy](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeRdGy) - ColorBrewer RdGy scheme. +* [d3.schemeRdYlBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeRdYlBu) - ColorBrewer RdYlBu scheme. +* [d3.schemeRdYlGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeRdYlGn) - ColorBrewer RdYlGn scheme. +* [d3.schemeSpectral](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeSpectral) - ColorBrewer spectral scheme. + +### Sequential (Single Hue) + +* [d3.interpolateBlues](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateBlues) - +* [d3.interpolateGreens](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateGreens) - +* [d3.interpolateGreys](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateGreys) - +* [d3.interpolateOranges](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateOranges) - +* [d3.interpolatePurples](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolatePurples) - +* [d3.interpolateReds](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateReds) - +* [d3.schemeBlues](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeBlues) - +* [d3.schemeGreens](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeGreens) - +* [d3.schemeGreys](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeGreys) - +* [d3.schemeOranges](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeOranges) - +* [d3.schemePurples](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePurples) - +* [d3.schemeReds](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeReds) - + +### Sequential (Multi-Hue) + +* [d3.interpolateBuGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateBuGn) - ColorBrewer BuGn interpolator. +* [d3.interpolateBuPu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateBuPu) - ColorBrewer BuPu interpolator. +* [d3.interpolateCividis](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateCividis) - cividis interpolator. +* [d3.interpolateCool](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateCool) - cool interpolator. +* [d3.interpolateCubehelixDefault](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateCubehelixDefault) - cubehelix interpolator. +* [d3.interpolateGnBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateGnBu) - ColorBrewer GnBu interpolator. +* [d3.interpolateInferno](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateInferno) - inferno interpolator. +* [d3.interpolateMagma](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateMagma) - magma interpolator. +* [d3.interpolateOrRd](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateOrRd) - ColorBrewer OrRd interpolator. +* [d3.interpolatePlasma](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolatePlasma) - plasma interpolator. +* [d3.interpolatePuBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolatePuBu) - ColorBrewer PuBu interpolator. +* [d3.interpolatePuBuGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolatePuBuGn) - ColorBrewer PuBuGn interpolator. +* [d3.interpolatePuRd](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolatePuRd) - ColorBrewer PuRd interpolator. +* [d3.interpolateRdPu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateRdPu) - ColorBrewer RdPu interpolator. +* [d3.interpolateTurbo](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateTurbo) - turbo interpolator. +* [d3.interpolateViridis](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateViridis) - viridis interpolator. +* [d3.interpolateWarm](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateWarm) - warm interpolator. +* [d3.interpolateYlGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateYlGn) - ColorBrewer YlGn interpolator. +* [d3.interpolateYlGnBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateYlGnBu) - ColorBrewer YlGnBu interpolator. +* [d3.interpolateYlOrBr](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateYlOrBr) - ColorBrewer YlOrBr interpolator. +* [d3.interpolateYlOrRd](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateYlOrRd) - ColorBrewer YlOrRd interpolator. +* [d3.schemeBuGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeBuGn) - ColorBrewer BuGn scheme. +* [d3.schemeBuPu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeBuPu) - ColorBrewer BuPu scheme. +* [d3.schemeGnBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeGnBu) - ColorBrewer GnBu scheme. +* [d3.schemeOrRd](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeOrRd) - ColorBrewer OrRd scheme. +* [d3.schemePuBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePuBu) - ColorBrewer PuBu scheme. +* [d3.schemePuBuGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePuBuGn) - ColorBrewer PuBuGn scheme. +* [d3.schemePuRd](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemePuRd) - ColorBrewer PuRd scheme. +* [d3.schemeRdPu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeRdPu) - ColorBrewer RdPu scheme. +* [d3.schemeYlGn](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeYlGn) - ColorBrewer YlGn scheme. +* [d3.schemeYlGnBu](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeYlGnBu) - ColorBrewer YlGnBu scheme. +* [d3.schemeYlOrBr](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeYlOrBr) - ColorBrewer YlOrBr scheme. +* [d3.schemeYlOrRd](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#schemeYlOrRd) - ColorBrewer YlOrRd scheme. + +### Cyclical + +* [d3.interpolateRainbow](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateRainbow) - the “less-angry” rainbow +* [d3.interpolateSinebow](https://github.com/d3/d3-scale-chromatic/blob/v2.0.0/README.md#interpolateSinebow) - the “sinebow” smooth rainbow + +## [Contours (d3-contour)](https://github.com/d3/d3-contour/tree/v2.0.0) + +Compute contour polygons using marching squares. + +* [d3.contours](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#contours) - create a new contour generator. +* [*contours*](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#_contours) - compute the contours for a given grid of values. +* [*contours*.contour](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#contours_contour) - compute a contour for a given value. +* [*contours*.size](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#contours_size) - set the size of a contour generator. +* [*contours*.smooth](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#contours_smooth) - set whether or not the generated contours are smoothed. +* [*contours*.thresholds](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#contours_thresholds) - set the thresholds of a contour generator. +* [d3.contourDensity](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#contourDensity) - create a new density estimator. +* [*density*](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#_density) - estimate the density of a given array of samples. +* [*density*.x](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#density_x) - set the *x* accessor of the density estimator. +* [*density*.y](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#density_y) - set the *y* accessor of the density estimator. +* [*density*.weight](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#density_weight) - set the *weight* accessor of the density estimator. +* [*density*.size](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#density_size) - set the size of the density estimator. +* [*density*.cellSize](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#density_cellSize) - set the cell size of the density estimator. +* [*density*.thresholds](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#density_thresholds) - set the thresholds of the density estimator. +* [*density*.bandwidth](https://github.com/d3/d3-contour/blob/v2.0.0/README.md#density_bandwidth) - set the bandwidth of the density estimator. + +## [Voronoi Diagrams (d3-delaunay)](https://github.com/d3/d3-delaunay/tree/v5.3.0) + +Compute the Voronoi diagram of a set of two-dimensional points. + +* [new Delaunay](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#new_Delaunay) - create a delaunay triangulation for an array of point coordinates. +* [Delaunay.from](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_from) - create a delaunay triangulation for an iterable of points. +* [*delaunay*.points](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_points) - the coordinates of the points. +* [*delaunay*.halfedges](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_halfedges) - the delaunay halfedges. +* [*delaunay*.hull](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_hull) - the convex hull as point indices. +* [*delaunay*.triangles](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_triangles) - the delaunay triangles. +* [*delaunay*.inedges](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_inedges) - the delaunay inedges +* [*delaunay*.find](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_find) - find the closest point in the delaunay triangulation. +* [*delaunay*.neighbors](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_neighbors) - the neighbors of a point in the delaunay triangulation. +* [*delaunay*.render](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_render) - render the edges of the delaunay triangulation. +* [*delaunay*.renderHull](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_renderHull) - render the convex hull. +* [*delaunay*.renderTriangle](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_renderTriangle) - render a triangle. +* [*delaunay*.renderPoints](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_renderPoints) - render the points. +* [*delaunay*.hullPolygon](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_hullPolygon) - the closed convex hull as point coordinates. +* [*delaunay*.trianglePolygons](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_trianglePolygons) - iterate over all the triangles as polygons. +* [*delaunay*.trianglePolygon](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_trianglePolygon) - return a triangle as a polygon. +* [*delaunay*.update](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_update) - update a delaunay triangulation in place. +* [*delaunay*.voronoi](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#delaunay_voronoi) - compute the voronoi diagram associated with a delaunay triangulation. +* [*voronoi*.delaunay](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_delaunay) - the voronoi diagram’s source delaunay triangulation. +* [*voronoi*.circumcenters](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_circumcenters) - the triangles’ circumcenters. +* [*voronoi*.vectors](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_vectors) - directions for the outer (infinite) cells of the voronoi diagram. +* [*voronoi*.xmin](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_xmin) - set the *xmin* bound of the extent. +* [*voronoi*.ymin](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_ymin) - set the *ymin* bound of the extent. +* [*voronoi*.xmax](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_xmax) - set the *xmax* bound of the extent. +* [*voronoi*.ymax](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_ymax) - set the *ymax* bound of the extent. +* [*voronoi*.contains](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_contains) - test whether a point is inside a voronoi cell. +* [*voronoi*.neighbors](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_neighbors) - the neighbors of a point in the voronoi diagram. +* [*voronoi*.render](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_render) - render the mesh of voronoi cells. +* [*voronoi*.renderBounds](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_renderBounds) - render the extent. +* [*voronoi*.renderCell](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_renderCell) - render a voronoi cell. +* [*voronoi*.cellPolygons](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_cellPolygons) - iterate over all the cells as polygons. +* [*voronoi*.cellPolygon](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_cellPolygon) - return a cell as a polygon. +* [*voronoi*.update](https://github.com/d3/d3-delaunay/blob/v5.3.0/README.md#voronoi_update) - update a voronoi diagram in place. + +## [Dispatches (d3-dispatch)](https://github.com/d3/d3-dispatch/tree/v2.0.0) + +Separate concerns using named callbacks. + +* [d3.dispatch](https://github.com/d3/d3-dispatch/blob/v2.0.0/README.md#dispatch) - create a custom event dispatcher. +* [*dispatch*.on](https://github.com/d3/d3-dispatch/blob/v2.0.0/README.md#dispatch_on) - register or unregister an event listener. +* [*dispatch*.copy](https://github.com/d3/d3-dispatch/blob/v2.0.0/README.md#dispatch_copy) - create a copy of a dispatcher. +* [*dispatch*.call](https://github.com/d3/d3-dispatch/blob/v2.0.0/README.md#dispatch_call) - dispatch an event to registered listeners. +* [*dispatch*.apply](https://github.com/d3/d3-dispatch/blob/v2.0.0/README.md#dispatch_apply) - dispatch an event to registered listeners. + +## [Dragging (d3-drag)](https://github.com/d3/d3-drag/tree/v2.0.0) + +Drag and drop SVG, HTML or Canvas using mouse or touch input. + +* [d3.drag](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#drag) - create a drag behavior. +* [*drag*](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#_drag) - apply the drag behavior to a selection. +* [*drag*.container](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#drag_container) - set the coordinate system. +* [*drag*.filter](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#drag_filter) - ignore some initiating input events. +* [*drag*.touchable](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#drag_touchable) - set the touch support detector. +* [*drag*.subject](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#drag_subject) - set the thing being dragged. +* [*drag*.clickDistance](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#drag_clickDistance) - set the click distance threshold. +* [*drag*.on](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#drag_on) - listen for drag events. +* [d3.dragDisable](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#dragDisable) - prevent native drag-and-drop and text selection. +* [d3.dragEnable](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#dragEnable) - enable native drag-and-drop and text selection. +* [*event*.on](https://github.com/d3/d3-drag/blob/v2.0.0/README.md#event_on) - listen for drag events on the current gesture. + +## [Delimiter-Separated Values (d3-dsv)](https://github.com/d3/d3-dsv/tree/v2.0.0) + +Parse and format delimiter-separated values, most commonly CSV and TSV. + +* [d3.csvParse](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#csvParse) - parse the given CSV string, returning an array of objects. +* [d3.csvParseRows](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#csvParseRows) - parse the given CSV string, returning an array of rows. +* [d3.csvFormat](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#csvFormat) - format the given array of objects as CSV. +* [d3.csvFormatBody](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#csvFormatBody) - format the given array of objects as CSV. +* [d3.csvFormatRows](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#csvFormatRows) - format the given array of rows as CSV. +* [d3.csvFormatRow](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#csvFormatRow) - format the given row as CSV. +* [d3.csvFormatValue](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#csvFormatValue) - format the given value as CSV. +* [d3.tsvParse](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#tsvParse) - parse the given TSV string, returning an array of objects. +* [d3.tsvParseRows](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#tsvParseRows) - parse the given TSV string, returning an array of rows. +* [d3.tsvFormat](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#tsvFormat) - format the given array of objects as TSV. +* [d3.tsvFormatBody](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#tsvFormatBody) - format the given array of objects as TSV. +* [d3.tsvFormatRows](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#tsvFormatRows) - format the given array of rows as TSV. +* [d3.tsvFormatRow](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#tsvFormatRow) - format the given row as TSV. +* [d3.tsvFormatValue](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#tsvFormatValue) - format the given value as TSV. +* [d3.dsvFormat](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#dsvFormat) - create a new parser and formatter for the given delimiter. +* [*dsv*.parse](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#dsv_parse) - parse the given string, returning an array of objects. +* [*dsv*.parseRows](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#dsv_parseRows) - parse the given string, returning an array of rows. +* [*dsv*.format](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#dsv_format) - format the given array of objects. +* [*dsv*.formatBody](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#dsv_formatBody) - format the given array of objects. +* [*dsv*.formatRows](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#dsv_formatRows) - format the given array of rows. +* [*dsv*.formatRow](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#dsv_formatRow) - format the given row. +* [*dsv*.formatValue](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#dsv_formatValue) - format the given value. +* [d3.autoType](https://github.com/d3/d3-dsv/blob/v2.0.0/README.md#autoType) - automatically infer value types for the given object. + +## [Easings (d3-ease)](https://github.com/d3/d3-ease/tree/v2.0.0) + +Easing functions for smooth animation. + +* [*ease*](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#_ease) - ease the given normalized time. +* [d3.easeLinear](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeLinear) - linear easing; the identity function. +* [d3.easePolyIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easePolyIn) - polynomial easing; raises time to the given power. +* [d3.easePolyOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easePolyOut) - reverse polynomial easing. +* [d3.easePoly](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easePoly) - an alias for easePolyInOut. +* [d3.easePolyInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easePolyInOut) - symmetric polynomial easing. +* [*poly*.exponent](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#poly_exponent) - specify the polynomial exponent. +* [d3.easeQuadIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeQuadIn) - quadratic easing; squares time. +* [d3.easeQuadOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeQuadOut) - reverse quadratic easing. +* [d3.easeQuad](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeQuad) - an alias for easeQuadInOut. +* [d3.easeQuadInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeQuadInOut) - symmetric quadratic easing. +* [d3.easeCubicIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeCubicIn) - cubic easing; cubes time. +* [d3.easeCubicOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeCubicOut) - reverse cubic easing. +* [d3.easeCubic](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeCubic) - an alias for easeCubicInOut. +* [d3.easeCubicInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeCubicInOut) - symmetric cubic easing. +* [d3.easeSinIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeSinIn) - sinusoidal easing. +* [d3.easeSinOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeSinOut) - reverse sinusoidal easing. +* [d3.easeSin](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeSin) - an alias for easeSinInOut. +* [d3.easeSinInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeSinInOut) - symmetric sinusoidal easing. +* [d3.easeExpIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeExpIn) - exponential easing. +* [d3.easeExpOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeExpOut) - reverse exponential easing. +* [d3.easeExp](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeExp) - an alias for easeExpInOut. +* [d3.easeExpInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeExpInOut) - symmetric exponential easing. +* [d3.easeCircleIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeCircleIn) - circular easing. +* [d3.easeCircleOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeCircleOut) - reverse circular easing. +* [d3.easeCircle](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeCircle) - an alias for easeCircleInOut. +* [d3.easeCircleInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeCircleInOut) - symmetric circular easing. +* [d3.easeElasticIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeElasticIn) - elastic easing, like a rubber band. +* [d3.easeElastic](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeElastic) - an alias for easeElasticOut. +* [d3.easeElasticOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeElasticOut) - reverse elastic easing. +* [d3.easeElasticInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeElasticInOut) - symmetric elastic easing. +* [*elastic*.amplitude](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#elastic_amplitude) - specify the elastic amplitude. +* [*elastic*.period](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#elastic_period) - specify the elastic period. +* [d3.easeBackIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeBackIn) - anticipatory easing, like a dancer bending his knees before jumping. +* [d3.easeBackOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeBackOut) - reverse anticipatory easing. +* [d3.easeBack](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeBack) - an alias for easeBackInOut. +* [d3.easeBackInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeBackInOut) - symmetric anticipatory easing. +* [*back*.overshoot](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#back_overshoot) - specify the amount of overshoot. +* [d3.easeBounceIn](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeBounceIn) - bounce easing, like a rubber ball. +* [d3.easeBounce](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeBounce) - an alias for easeBounceOut. +* [d3.easeBounceOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeBounceOut) - reverse bounce easing. +* [d3.easeBounceInOut](https://github.com/d3/d3-ease/blob/v2.0.0/README.md#easeBounceInOut) - symmetric bounce easing. + +## [Fetches (d3-fetch)](https://github.com/d3/d3-fetch/tree/v2.0.0) + +Convenience methods on top of the Fetch API. + +* [d3.blob](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#blob) - get a file as a blob. +* [d3.buffer](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#buffer) - get a file as an array buffer. +* [d3.csv](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#csv) - get a comma-separated values (CSV) file. +* [d3.dsv](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#dsv) - get a delimiter-separated values (CSV) file. +* [d3.html](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#html) - get an HTML file. +* [d3.image](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#image) - get an image. +* [d3.json](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#json) - get a JSON file. +* [d3.svg](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#svg) - get an SVG file. +* [d3.text](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#text) - get a plain text file. +* [d3.tsv](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#tsv) - get a tab-separated values (TSV) file. +* [d3.xml](https://github.com/d3/d3-fetch/blob/v2.0.0/README.md#xml) - get an XML file. + +## [Forces (d3-force)](https://github.com/d3/d3-force/tree/v2.1.1) + +Force-directed graph layout using velocity Verlet integration. + +* [d3.forceSimulation](https://github.com/d3/d3-force/blob/v2.1.1/README.md#forceSimulation) - create a new force simulation. +* [*simulation*.restart](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_restart) - reheat and restart the simulation’s timer. +* [*simulation*.stop](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_stop) - stop the simulation’s timer. +* [*simulation*.tick](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_tick) - advance the simulation one step. +* [*simulation*.nodes](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_nodes) - set the simulation’s nodes. +* [*simulation*.alpha](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_alpha) - set the current alpha. +* [*simulation*.alphaMin](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_alphaMin) - set the minimum alpha threshold. +* [*simulation*.alphaDecay](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_alphaDecay) - set the alpha exponential decay rate. +* [*simulation*.alphaTarget](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_alphaTarget) - set the target alpha. +* [*simulation*.velocityDecay](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_velocityDecay) - set the velocity decay rate. +* [*simulation*.force](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_force) - add or remove a force. +* [*simulation*.find](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_find) - find the closest node to the given position. +* [*simulation*.randomSource](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_randomSource) - set the simulation’s random source. +* [*simulation*.on](https://github.com/d3/d3-force/blob/v2.1.1/README.md#simulation_on) - add or remove an event listener. +* [*force*](https://github.com/d3/d3-force/blob/v2.1.1/README.md#_force) - apply the force. +* [*force*.initialize](https://github.com/d3/d3-force/blob/v2.1.1/README.md#force_initialize) - initialize the force with the given nodes. +* [d3.forceCenter](https://github.com/d3/d3-force/blob/v2.1.1/README.md#forceCenter) - create a centering force. +* [*center*.x](https://github.com/d3/d3-force/blob/v2.1.1/README.md#center_x) - set the center *x*-coordinate. +* [*center*.y](https://github.com/d3/d3-force/blob/v2.1.1/README.md#center_y) - set the center *y*-coordinate. +* [*center*.strength](https://github.com/d3/d3-force/blob/v2.1.1/README.md#center_strength) - set the strength of the centering force. +* [d3.forceCollide](https://github.com/d3/d3-force/blob/v2.1.1/README.md#forceCollide) - create a circle collision force. +* [*collide*.radius](https://github.com/d3/d3-force/blob/v2.1.1/README.md#collide_radius) - set the circle radius. +* [*collide*.strength](https://github.com/d3/d3-force/blob/v2.1.1/README.md#collide_strength) - set the collision resolution strength. +* [*collide*.iterations](https://github.com/d3/d3-force/blob/v2.1.1/README.md#collide_iterations) - set the number of iterations. +* [d3.forceLink](https://github.com/d3/d3-force/blob/v2.1.1/README.md#forceLink) - create a link force. +* [*link*.links](https://github.com/d3/d3-force/blob/v2.1.1/README.md#link_links) - set the array of links. +* [*link*.id](https://github.com/d3/d3-force/blob/v2.1.1/README.md#link_id) - link nodes by numeric index or string identifier. +* [*link*.distance](https://github.com/d3/d3-force/blob/v2.1.1/README.md#link_distance) - set the link distance. +* [*link*.strength](https://github.com/d3/d3-force/blob/v2.1.1/README.md#link_strength) - set the link strength. +* [*link*.iterations](https://github.com/d3/d3-force/blob/v2.1.1/README.md#link_iterations) - set the number of iterations. +* [d3.forceManyBody](https://github.com/d3/d3-force/blob/v2.1.1/README.md#forceManyBody) - create a many-body force. +* [*manyBody*.strength](https://github.com/d3/d3-force/blob/v2.1.1/README.md#manyBody_strength) - set the force strength. +* [*manyBody*.theta](https://github.com/d3/d3-force/blob/v2.1.1/README.md#manyBody_theta) - set the Barnes–Hut approximation accuracy. +* [*manyBody*.distanceMin](https://github.com/d3/d3-force/blob/v2.1.1/README.md#manyBody_distanceMin) - limit the force when nodes are close. +* [*manyBody*.distanceMax](https://github.com/d3/d3-force/blob/v2.1.1/README.md#manyBody_distanceMax) - limit the force when nodes are far. +* [d3.forceX](https://github.com/d3/d3-force/blob/v2.1.1/README.md#forceX) - create an *x*-positioning force. +* [*x*.strength](https://github.com/d3/d3-force/blob/v2.1.1/README.md#x_strength) - set the force strength. +* [*x*.x](https://github.com/d3/d3-force/blob/v2.1.1/README.md#x_x) - set the target *x*-coordinate. +* [d3.forceY](https://github.com/d3/d3-force/blob/v2.1.1/README.md#forceY) - create an *y*-positioning force. +* [*y*.strength](https://github.com/d3/d3-force/blob/v2.1.1/README.md#y_strength) - set the force strength. +* [*y*.y](https://github.com/d3/d3-force/blob/v2.1.1/README.md#y_y) - set the target *y*-coordinate. +* [d3.forceRadial](https://github.com/d3/d3-force/blob/v2.1.1/README.md#forceRadial) - create a radial positioning force. +* [*radial*.strength](https://github.com/d3/d3-force/blob/v2.1.1/README.md#radial_strength) - set the force strength. +* [*radial*.radius](https://github.com/d3/d3-force/blob/v2.1.1/README.md#radial_radius) - set the target radius. +* [*radial*.x](https://github.com/d3/d3-force/blob/v2.1.1/README.md#radial_x) - set the target center *x*-coordinate. +* [*radial*.y](https://github.com/d3/d3-force/blob/v2.1.1/README.md#radial_y) - set the target center *y*-coordinate. + +## [Number Formats (d3-format)](https://github.com/d3/d3-format/tree/v2.0.0) + +Format numbers for human consumption. + +* [d3.format](https://github.com/d3/d3-format/blob/v2.0.0/README.md#format) - alias for *locale*.format on the default locale. +* [d3.formatPrefix](https://github.com/d3/d3-format/blob/v2.0.0/README.md#formatPrefix) - alias for *locale*.formatPrefix on the default locale. +* [*locale*.format](https://github.com/d3/d3-format/blob/v2.0.0/README.md#locale_format) - create a number format. +* [*locale*.formatPrefix](https://github.com/d3/d3-format/blob/v2.0.0/README.md#locale_formatPrefix) - create a SI-prefix number format. +* [d3.formatSpecifier](https://github.com/d3/d3-format/blob/v2.0.0/README.md#formatSpecifier) - parse a number format specifier. +* [new d3.FormatSpecifier](https://github.com/d3/d3-format/blob/v2.0.0/README.md#FormatSpecifier) - augments a number format specifier object. +* [d3.precisionFixed](https://github.com/d3/d3-format/blob/v2.0.0/README.md#precisionFixed) - compute decimal precision for fixed-point notation. +* [d3.precisionPrefix](https://github.com/d3/d3-format/blob/v2.0.0/README.md#precisionPrefix) - compute decimal precision for SI-prefix notation. +* [d3.precisionRound](https://github.com/d3/d3-format/blob/v2.0.0/README.md#precisionRound) - compute significant digits for rounded notation. +* [d3.formatLocale](https://github.com/d3/d3-format/blob/v2.0.0/README.md#formatLocale) - define a custom locale. +* [d3.formatDefaultLocale](https://github.com/d3/d3-format/blob/v2.0.0/README.md#formatDefaultLocale) - define the default locale. + +## [Geographies (d3-geo)](https://github.com/d3/d3-geo/tree/v2.0.0) + +Geographic projections, shapes and math. + +### [Paths](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#paths) + +* [d3.geoPath](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoPath) - create a new geographic path generator. +* [*path*](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#_path) - project and render the specified feature. +* [*path*.area](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#path_area) - compute the projected planar area of a given feature. +* [*path*.bounds](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#path_bounds) - compute the projected planar bounding box of a given feature. +* [*path*.centroid](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#path_centroid) - compute the projected planar centroid of a given feature. +* [*path*.measure](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#path_measure) - compute the projected planar length of a given feature. +* [*path*.projection](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#path_projection) - set the geographic projection. +* [*path*.context](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#path_context) - set the render context. +* [*path*.pointRadius](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#path_pointRadius) - set the radius to display point features. + +### [Projections](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projections) + +* [*projection*](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#_projection) - project the specified point from the sphere to the plane. +* [*projection*.invert](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_invert) - unproject the specified point from the plane to the sphere. +* [*projection*.stream](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_stream) - wrap the specified stream to project geometry. +* [*projection*.preclip](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_preclip) - set the projection’s spherical clipping function. +* [*projection*.postclip](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_postclip) - set the projection’s cartesian clipping function. +* [*projection*.clipAngle](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_clipAngle) - set the radius of the clip circle. +* [*projection*.clipExtent](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_clipExtent) - set the viewport clip extent, in pixels. +* [*projection*.scale](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_scale) - set the scale factor. +* [*projection*.translate](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_translate) - set the translation offset. +* [*projection*.center](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_center) - set the center point. +* [*projection*.angle](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_angle) - set the post-projection rotation. +* [*projection*.reflectX](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_reflectX) - reflect the *x*-dimension. +* [*projection*.reflectY](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_reflectY) - reflect the *y*-dimension. +* [*projection*.rotate](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_rotate) - set the three-axis spherical rotation angles. +* [*projection*.precision](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_precision) - set the precision threshold for adaptive sampling. +* [*projection*.fitExtent](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_fitExtent) - set the scale and translate to fit a GeoJSON object. +* [*projection*.fitSize](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_fitSize) - set the scale and translate to fit a GeoJSON object. +* [*projection*.fitWidth](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_fitWidth) - set the scale and translate to fit a GeoJSON object. +* [*projection*.fitHeight](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#projection_fitHeight) - set the scale and translate to fit a GeoJSON object. +* [d3.geoAzimuthalEqualArea](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoAzimuthalEqualArea) - the azimuthal equal-area projection. +* [d3.geoAzimuthalEqualAreaRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoAzimuthalEqualAreaRaw) - the raw azimuthal equal-area projection. +* [d3.geoAzimuthalEquidistant](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoAzimuthalEquidistant) - the azimuthal equidistant projection. +* [d3.geoAzimuthalEquidistantRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoAzimuthalEquidistantRaw) - the raw azimuthal equidistant projection. +* [d3.geoGnomonic](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoGnomonic) - the gnomonic projection. +* [d3.geoGnomonicRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoGnomonicRaw) - the raw gnomonic projection. +* [d3.geoOrthographic](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoOrthographic) - the azimuthal orthographic projection. +* [d3.geoOrthographicRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoOrthographicRaw) - the raw azimuthal orthographic projection. +* [d3.geoStereographic](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoStereographic) - the azimuthal stereographic projection. +* [d3.geoStereographicRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoStereographicRaw) - the raw azimuthal stereographic projection. +* [d3.geoEqualEarth](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoEqualEarth) - the Equal Earth projection. +* [d3.geoEqualEarthRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoEqualEarthRaw) - the raw Equal Earth projection. +* [d3.geoAlbersUsa](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoAlbersUsa) - a composite Albers projection for the United States. +* [*conic*.parallels](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#conic_parallels) - set the two standard parallels. +* [d3.geoAlbers](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoAlbers) - the Albers equal-area conic projection. +* [d3.geoConicConformal](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoConicConformal) - the conic conformal projection. +* [d3.geoConicConformalRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoConicConformalRaw) - the raw conic conformal projection. +* [d3.geoConicEqualArea](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoConicEqualArea) - the conic equal-area (Albers) projection. +* [d3.geoConicEqualAreaRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoConicEqualAreaRaw) - the raw conic equal-area (Albers) projection. +* [d3.geoConicEquidistant](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoConicEquidistant) - the conic equidistant projection. +* [d3.geoConicEquidistantRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoConicEquidistantRaw) - the raw conic equidistant projection. +* [d3.geoEquirectangular](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoEquirectangular) - the equirectangular (plate carreé) projection. +* [d3.geoEquirectangularRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoEquirectangularRaw) - the raw equirectangular (plate carreé) projection. +* [d3.geoMercator](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoMercator) - the spherical Mercator projection. +* [d3.geoMercatorRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoMercatorRaw) - the raw Mercator projection. +* [d3.geoTransverseMercator](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoTransverseMercator) - the transverse spherical Mercator projection. +* [d3.geoTransverseMercatorRaw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoTransverseMercatorRaw) - the raw transverse spherical Mercator projection. +* [d3.geoNaturalEarth1](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoNaturalEarth1) - the Equal Earth projection, version 1. +* [d3.geoNaturalEarth1Raw](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoNaturalEarth1Raw) - the raw Equal Earth projection, version 1 + +### [Raw projections](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#raw-projections) + +* [*project*](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#_project) - project the specified point from the sphere to the plane. +* [*project*.invert](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#project_invert) - unproject the specified point from the plane to the sphere. +* [d3.geoProjection](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoProjection) - create a custom projection. +* [d3.geoProjectionMutator](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoProjectionMutator) - create a custom configurable projection. + +### [Spherical Math](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#spherical-math) + +* [d3.geoArea](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoArea) - compute the spherical area of a given feature. +* [d3.geoBounds](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoBounds) - compute the latitude-longitude bounding box for a given feature. +* [d3.geoCentroid](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoCentroid) - compute the spherical centroid of a given feature. +* [d3.geoDistance](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoDistance) - compute the great-arc distance between two points. +* [d3.geoLength](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoLength) - compute the length of a line string or the perimeter of a polygon. +* [d3.geoInterpolate](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoInterpolate) - interpolate between two points along a great arc. +* [d3.geoContains](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoContains) - test whether a point is inside a given feature. +* [d3.geoRotation](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoRotation) - create a rotation function for the specified angles. +* [*rotation*](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#_rotation) - rotate the given point around the sphere. +* [*rotation*.invert](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#rotation_invert) - unrotate the given point around the sphere. + +### [Spherical Shapes](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#spherical-shapes) + +* [d3.geoCircle](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoCircle) - create a circle generator. +* [*circle*](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#_circle) - generate a piecewise circle as a Polygon. +* [*circle*.center](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#circle_center) - specify the circle center in latitude and longitude. +* [*circle*.radius](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#circle_radius) - specify the angular radius in degrees. +* [*circle*.precision](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#circle_precision) - specify the precision of the piecewise circle. +* [d3.geoGraticule](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoGraticule) - create a graticule generator. +* [*graticule*](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#_graticule) - generate a MultiLineString of meridians and parallels. +* [*graticule*.lines](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_lines) - generate an array of LineStrings of meridians and parallels. +* [*graticule*.outline](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_outline) - generate a Polygon of the graticule’s extent. +* [*graticule*.extent](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_extent) - get or set the major & minor extents. +* [*graticule*.extentMajor](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_extentMajor) - get or set the major extent. +* [*graticule*.extentMinor](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_extentMinor) - get or set the minor extent. +* [*graticule*.step](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_step) - get or set the major & minor step intervals. +* [*graticule*.stepMajor](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_stepMajor) - get or set the major step intervals. +* [*graticule*.stepMinor](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_stepMinor) - get or set the minor step intervals. +* [*graticule*.precision](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#graticule_precision) - get or set the latitudinal precision. +* [d3.geoGraticule10](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoGraticule10) - generate the default 10° global graticule. + +### [Streams](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#streams) + +* [d3.geoStream](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoStream) - convert a GeoJSON object to a geometry stream. +* [*stream*.point](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#stream_point) - indicates a point with the specified coordinates. +* [*stream*.lineStart](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#stream_lineStart) - indicates the start of a line or ring. +* [*stream*.lineEnd](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#stream_lineEnd) - indicates the end of a line or ring. +* [*stream*.polygonStart](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#stream_polygonStart) - indicates the start of a polygon. +* [*stream*.polygonEnd](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#stream_polygonEnd) - indicates the end of a polygon. +* [*stream*.sphere](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#stream_sphere) - indicates the sphere. + +### [Transforms](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#transforms) + +* [d3.geoTransform](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoTransform) - define a custom geometry transform. +* [d3.geoIdentity](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoIdentity) - scale, translate or clip planar geometry. + +### [Clipping](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#clipping) + +* [*preclip*](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#preclip) - pre-clipping in geographic coordinates. +* [*postclip*](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#postclip) - post-clipping in planar coordinates. +* [d3.geoClipAntimeridian](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoClipAntimeridian) - cuts spherical geometries that cross the antimeridian. +* [d3.geoClipCircle](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoClipCircle) - clips spherical geometries to a small circle. +* [d3.geoClipRectangle](https://github.com/d3/d3-geo/blob/v2.0.0/README.md#geoClipRectangle) - clips planar geometries to a rectangular viewport. + +## [Hierarchies (d3-hierarchy)](https://github.com/d3/d3-hierarchy/tree/v2.0.0) + +Layout algorithms for visualizing hierarchical data. + +* [d3.hierarchy](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#hierarchy) - constructs a root node from hierarchical data. +* [*node*.ancestors](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_ancestors) - generate an array of ancestors. +* [*node*.descendants](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_descendants) - generate an array of descendants. +* [*node*.leaves](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_leaves) - generate an array of leaves. +* [*node*.find](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_find) - find a node in the hierarchy. +* [*node*.path](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_path) - generate the shortest path to another node. +* [*node*.links](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_links) - generate an array of links. +* [*node*.sum](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_sum) - evaluate and aggregate quantitative values. +* [*node*.count](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_count) - count the number of leaves. +* [*node*.sort](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_sort) - sort all descendant siblings. +* [*node*[Symbol.iterator]](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_iterator) - iterate on a hierarchy. +* [*node*.each](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_each) - breadth-first traversal. +* [*node*.eachAfter](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_eachAfter) - post-order traversal. +* [*node*.eachBefore](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_eachBefore) - pre-order traversal. +* [*node*.copy](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#node_copy) - copy a hierarchy. +* [d3.stratify](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#stratify) - create a new stratify operator. +* [*stratify*](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#_stratify) - construct a root node from tabular data. +* [*stratify*.id](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#stratify_id) - set the node id accessor. +* [*stratify*.parentId](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#stratify_parentId) - set the parent node id accessor. +* [d3.cluster](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#cluster) - create a new cluster (dendrogram) layout. +* [*cluster*](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#_cluster) - layout the specified hierarchy in a dendrogram. +* [*cluster*.size](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#cluster_size) - set the layout size. +* [*cluster*.nodeSize](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#cluster_nodeSize) - set the node size. +* [*cluster*.separation](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#cluster_separation) - set the separation between leaves. +* [d3.tree](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#tree) - create a new tidy tree layout. +* [*tree*](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#_tree) - layout the specified hierarchy in a tidy tree. +* [*tree*.size](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#tree_size) - set the layout size. +* [*tree*.nodeSize](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#tree_nodeSize) - set the node size. +* [*tree*.separation](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#tree_separation) - set the separation between nodes. +* [d3.treemap](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap) - create a new treemap layout. +* [*treemap*](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#_treemap) - layout the specified hierarchy as a treemap. +* [*treemap*.tile](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_tile) - set the tiling method. +* [*treemap*.size](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_size) - set the layout size. +* [*treemap*.round](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_round) - set whether the output coordinates are rounded. +* [*treemap*.padding](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_padding) - set the padding. +* [*treemap*.paddingInner](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_paddingInner) - set the padding between siblings. +* [*treemap*.paddingOuter](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_paddingOuter) - set the padding between parent and children. +* [*treemap*.paddingTop](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_paddingTop) - set the padding between the parent’s top edge and children. +* [*treemap*.paddingRight](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_paddingRight) - set the padding between the parent’s right edge and children. +* [*treemap*.paddingBottom](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_paddingBottom) - set the padding between the parent’s bottom edge and children. +* [*treemap*.paddingLeft](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemap_paddingLeft) - set the padding between the parent’s left edge and children. +* [d3.treemapBinary](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemapBinary) - tile using a balanced binary tree. +* [d3.treemapDice](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemapDice) - tile into a horizontal row. +* [d3.treemapSlice](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemapSlice) - tile into a vertical column. +* [d3.treemapSliceDice](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemapSliceDice) - alternate between slicing and dicing. +* [d3.treemapSquarify](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemapSquarify) - tile using squarified rows per Bruls *et. al.* +* [d3.treemapResquarify](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#treemapResquarify) - like d3.treemapSquarify, but performs stable updates. +* [*squarify*.ratio](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#squarify_ratio) - set the desired rectangle aspect ratio. +* [d3.partition](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#partition) - create a new partition (icicle or sunburst) layout. +* [*partition*](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#_partition) - layout the specified hierarchy as a partition diagram. +* [*partition*.size](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#partition_size) - set the layout size. +* [*partition*.round](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#partition_round) - set whether the output coordinates are rounded. +* [*partition*.padding](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#partition_padding) - set the padding. +* [d3.pack](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#pack) - create a new circle-packing layout. +* [*pack*](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#_pack) - layout the specified hierarchy using circle-packing. +* [*pack*.radius](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#pack_radius) - set the radius accessor. +* [*pack*.size](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#pack_size) - set the layout size. +* [*pack*.padding](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#pack_padding) - set the padding. +* [d3.packSiblings](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#packSiblings) - pack the specified array of circles. +* [d3.packEnclose](https://github.com/d3/d3-hierarchy/blob/v2.0.0/README.md#packEnclose) - enclose the specified array of circles. + +## [Interpolators (d3-interpolate)](https://github.com/d3/d3-interpolate/tree/v2.0.1) + +Interpolate numbers, colors, strings, arrays, objects, whatever! + +* [d3.interpolate](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolate) - interpolate arbitrary values. +* [d3.interpolateNumber](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateNumber) - interpolate numbers. +* [d3.interpolateRound](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateRound) - interpolate integers. +* [d3.interpolateString](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateString) - interpolate strings with embedded numbers. +* [d3.interpolateDate](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateDate) - interpolate dates. +* [d3.interpolateArray](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateArray) - interpolate arrays of arbitrary values. +* [d3.interpolateNumberArray](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateNumberArray) - interpolate arrays of numbers. +* [d3.interpolateObject](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateObject) - interpolate arbitrary objects. +* [d3.interpolateTransformCss](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateTransformCss) - interpolate 2D CSS transforms. +* [d3.interpolateTransformSvg](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateTransformSvg) - interpolate 2D SVG transforms. +* [d3.interpolateZoom](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateZoom) - zoom and pan between two views. +* [*interpolateZoom*.rho](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolate_rho) - set the curvature *rho* of the zoom interpolator. +* [d3.interpolateDiscrete](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateDiscrete) - generate a discrete interpolator from a set of values. +* [d3.quantize](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#quantize) - generate uniformly-spaced samples from an interpolator. +* [d3.interpolateRgb](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateRgb) - interpolate RGB colors. +* [d3.interpolateRgbBasis](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateRgbBasis) - generate a B-spline through a set of colors. +* [d3.interpolateRgbBasisClosed](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateRgbBasisClosed) - generate a closed B-spline through a set of colors. +* [d3.interpolateHsl](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateHsl) - interpolate HSL colors. +* [d3.interpolateHslLong](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateHslLong) - interpolate HSL colors, the long way. +* [d3.interpolateLab](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateLab) - interpolate Lab colors. +* [d3.interpolateHcl](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateHcl) - interpolate HCL colors. +* [d3.interpolateHclLong](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateHclLong) - interpolate HCL colors, the long way. +* [d3.interpolateCubehelix](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateCubehelix) - interpolate Cubehelix colors. +* [d3.interpolateCubehelixLong](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateCubehelixLong) - interpolate Cubehelix colors, the long way. +* [*interpolate*.gamma](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolate_gamma) - apply gamma correction during interpolation. +* [d3.interpolateHue](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateHue) - interpolate a hue angle. +* [d3.interpolateBasis](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateBasis) - generate a B-spline through a set of values. +* [d3.interpolateBasisClosed](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#interpolateBasisClosed) - generate a closed B-spline through a set of values. +* [d3.piecewise](https://github.com/d3/d3-interpolate/blob/v2.0.1/README.md#piecewise) - generate a piecewise linear interpolator from a set of values. + +## [Paths (d3-path)](https://github.com/d3/d3-path/tree/v2.0.0) + +Serialize Canvas path commands to SVG. + +* [d3.path](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path) - create a new path serializer. +* [*path*.moveTo](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_moveTo) - move to the given point. +* [*path*.closePath](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_closePath) - close the current subpath. +* [*path*.lineTo](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_lineTo) - draw a straight line segment. +* [*path*.quadraticCurveTo](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_quadraticCurveTo) - draw a quadratic Bézier segment. +* [*path*.bezierCurveTo](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_bezierCurveTo) - draw a cubic Bézier segment. +* [*path*.arcTo](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_arcTo) - draw a circular arc segment. +* [*path*.arc](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_arc) - draw a circular arc segment. +* [*path*.rect](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_rect) - draw a rectangle. +* [*path*.toString](https://github.com/d3/d3-path/blob/v2.0.0/README.md#path_toString) - serialize to an SVG path data string. + +## [Polygons (d3-polygon)](https://github.com/d3/d3-polygon/tree/v2.0.0) + +Geometric operations for two-dimensional polygons. + +* [d3.polygonArea](https://github.com/d3/d3-polygon/blob/v2.0.0/README.md#polygonArea) - compute the area of the given polygon. +* [d3.polygonCentroid](https://github.com/d3/d3-polygon/blob/v2.0.0/README.md#polygonCentroid) - compute the centroid of the given polygon. +* [d3.polygonHull](https://github.com/d3/d3-polygon/blob/v2.0.0/README.md#polygonHull) - compute the convex hull of the given points. +* [d3.polygonContains](https://github.com/d3/d3-polygon/blob/v2.0.0/README.md#polygonContains) - test whether a point is inside a polygon. +* [d3.polygonLength](https://github.com/d3/d3-polygon/blob/v2.0.0/README.md#polygonLength) - compute the length of the given polygon’s perimeter. + +## [Quadtrees (d3-quadtree)](https://github.com/d3/d3-quadtree/tree/v2.0.0) + +Two-dimensional recursive spatial subdivision. + +* [d3.quadtree](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree) - create a new, empty quadtree. +* [*quadtree*.x](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_x) - set the *x* accessor. +* [*quadtree*.y](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_y) - set the *y* accessor. +* [*quadtree*.extent](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_extent) - extend the quadtree to cover an extent. +* [*quadtree*.cover](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_cover) - extend the quadtree to cover a point. +* [*quadtree*.add](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_add) - add a datum to a quadtree. +* [*quadtree*.addAll](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_addAll) - add an array of data to a quadtree. +* [*quadtree*.remove](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_remove) - remove a datum from a quadtree. +* [*quadtree*.removeAll](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_removeAll) - remove an array of data from a quadtree. +* [*quadtree*.copy](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_copy) - create a copy of a quadtree. +* [*quadtree*.root](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_root) - get the quadtree’s root node. +* [*quadtree*.data](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_data) - retrieve all data from the quadtree. +* [*quadtree*.size](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_size) - count the number of data in the quadtree. +* [*quadtree*.find](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_find) - quickly find the closest datum in a quadtree. +* [*quadtree*.visit](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_visit) - selectively visit nodes in a quadtree. +* [*quadtree*.visitAfter](https://github.com/d3/d3-quadtree/blob/v2.0.0/README.md#quadtree_visitAfter) - visit all nodes in a quadtree. + +## [Random Numbers (d3-random)](https://github.com/d3/d3-random/tree/v2.2.2) + +Generate random numbers from various distributions. + +* [d3.randomUniform](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomUniform) - from a uniform distribution. +* [d3.randomInt](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomInt) - from a uniform integer distribution. +* [d3.randomNormal](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomNormal) - from a normal distribution. +* [d3.randomLogNormal](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomLogNormal) - from a log-normal distribution. +* [d3.randomBates](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomBates) - from a Bates distribution. +* [d3.randomIrwinHall](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomIrwinHall) - from an Irwin–Hall distribution. +* [d3.randomExponential](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomExponential) - from an exponential distribution. +* [d3.randomPareto](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomPareto) - from a Pareto distribution. +* [d3.randomBernoulli](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomBernoulli) - from a Bernoulli distribution. +* [d3.randomGeometric](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomGeometric) - from a geometric distribution. +* [d3.randomBinomial](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomBinomial) - from a binomial distribution. +* [d3.randomGamma](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomGamma) - from a gamma distribution. +* [d3.randomBeta](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomBeta) - from a beta distribution. +* [d3.randomWeibull](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomWeibull) - from a Weibull, Gumbel or Fréchet distribution. +* [d3.randomCauchy](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomCauchy) - from a Cauchy distribution. +* [d3.randomLogistic](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomLogistic) - from a logistic distribution. +* [d3.randomPoisson](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomPoisson) - from a Poisson distribution. +* [*random*.source](https://github.com/d3/d3-random/blob/v2.2.2/README.md#random_source) - set the source of randomness. +* [d3.randomLcg](https://github.com/d3/d3-random/blob/v2.2.2/README.md#randomLcg) - a seeded pseudorandom number generator. + +## [Scales (d3-scale)](https://github.com/d3/d3-scale/tree/v3.3.0) + +Encodings that map abstract data to visual representation. + +### [Continuous Scales](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous-scales) + +Map a continuous, quantitative domain to a continuous range. + +* [*continuous*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_continuous) - compute the range value corresponding to a given domain value. +* [*continuous*.invert](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_invert) - compute the domain value corresponding to a given range value. +* [*continuous*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_domain) - set the input domain. +* [*continuous*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_range) - set the output range. +* [*continuous*.rangeRound](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_rangeRound) - set the output range and enable rounding. +* [*continuous*.clamp](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_clamp) - enable clamping to the domain or range. +* [*continuous*.unknown](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_unknown) - set the output value for unknown inputs. +* [*continuous*.interpolate](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_interpolate) - set the output interpolator. +* [*continuous*.ticks](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_ticks) - compute representative values from the domain. +* [*continuous*.tickFormat](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_tickFormat) - format ticks for human consumption. +* [*continuous*.nice](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_nice) - extend the domain to nice round numbers. +* [*continuous*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#continuous_copy) - create a copy of this scale. +* [d3.tickFormat](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#tickFormat) - format ticks for human consumption. +* [d3.scaleLinear](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleLinear) - create a quantitative linear scale. +* [d3.scalePow](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scalePow) - create a quantitative power scale. +* [*pow*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_pow) - compute the range value corresponding to a given domain value. +* [*pow*.invert](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_invert) - compute the domain value corresponding to a given range value. +* [*pow*.exponent](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_exponent) - set the power exponent. +* [*pow*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_domain) - set the input domain. +* [*pow*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_range) - set the output range. +* [*pow*.rangeRound](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_rangeRound) - set the output range and enable rounding. +* [*pow*.clamp](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_clamp) - enable clamping to the domain or range. +* [*pow*.interpolate](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_interpolate) - set the output interpolator. +* [*pow*.ticks](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_ticks) - compute representative values from the domain. +* [*pow*.tickFormat](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_tickFormat) - format ticks for human consumption. +* [*pow*.nice](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_nice) - extend the domain to nice round numbers. +* [*pow*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#pow_copy) - create a copy of this scale. +* [d3.scaleSqrt](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleSqrt) - create a quantitative power scale with exponent 0.5. +* [d3.scaleLog](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleLog) - create a quantitative logarithmic scale. +* [*log*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_log) - compute the range value corresponding to a given domain value. +* [*log*.invert](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_invert) - compute the domain value corresponding to a given range value. +* [*log*.base](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_base) - set the logarithm base. +* [*log*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_domain) - set the input domain. +* [*log*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_range) - set the output range. +* [*log*.rangeRound](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_rangeRound) - set the output range and enable rounding. +* [*log*.clamp](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_clamp) - enable clamping to the domain or range. +* [*log*.interpolate](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_interpolate) - set the output interpolator. +* [*log*.ticks](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_ticks) - compute representative values from the domain. +* [*log*.tickFormat](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_tickFormat) - format ticks for human consumption. +* [*log*.nice](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_nice) - extend the domain to nice round numbers. +* [*log*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#log_copy) - create a copy of this scale. +* [d3.scaleSymlog](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleSymlog) - create a symmetric logarithmic scale. +* [*symlog*.constant](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#symlog_constant) - set the constant of a symlog scale. +* [d3.scaleIdentity](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleIdentity) - creates an identity scale. +* [d3.scaleRadial](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleRadial) - creates a radial scale. +* [d3.scaleTime](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleTime) - create a linear scale for time. +* [*time*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_time) - compute the range value corresponding to a given domain value. +* [*time*.invert](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_invert) - compute the domain value corresponding to a given range value. +* [*time*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_domain) - set the input domain. +* [*time*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_range) - set the output range. +* [*time*.rangeRound](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_rangeRound) - set the output range and enable rounding. +* [*time*.clamp](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_clamp) - enable clamping to the domain or range. +* [*time*.interpolate](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_interpolate) - set the output interpolator. +* [*time*.ticks](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_ticks) - compute representative values from the domain. +* [*time*.tickFormat](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_tickFormat) - format ticks for human consumption. +* [*time*.nice](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_nice) - extend the domain to nice round times. +* [*time*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#time_copy) - create a copy of this scale. +* [d3.scaleUtc](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleUtc) - create a linear scale for UTC. + +### [Sequential Scales](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#sequential-scales) + +Map a continuous, quantitative domain to a continuous, fixed interpolator. + +* [d3.scaleSequential](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleSequential) - create a sequential scale. +* [*sequential*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_sequential) - compute the range value corresponding to an input value. +* [*sequential*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#sequential_domain) - set the input domain. +* [*sequential*.clamp](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#sequential_clamp) - enable clamping to the domain. +* [*sequential*.interpolator](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#sequential_interpolator) - set the scale’s output interpolator. +* [*sequential*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#sequential_range) - set the output range. +* [*sequential*.rangeRound](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#sequential_rangeRound) - set the output range and enable rounding. +* [*sequential*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#sequential_copy) - create a copy of this scale. +* [d3.scaleSequentialLog](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleSequentialLog) - create a logarithmic sequential scale. +* [d3.scaleSequentialPow](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleSequentialPow) - create a power sequential scale. +* [d3.scaleSequentialSqrt](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleSequentialSqrt) - create a power sequential scale with exponent 0.5. +* [d3.scaleSequentialSymlog](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleSequentialSymlog) - create a symmetric logarithmic sequential scale. +* [d3.scaleSequentialQuantile](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleSequentialQuantile) - create a sequential scale using a *p*-quantile transform. +* [*sequentialQuantile*.quantiles](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#sequentialQuantile_quantiles) - return the scale’s quantiles. + +### [Diverging Scales](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#diverging-scales) + +Map a continuous, quantitative domain to a continuous, fixed interpolator. + +* [d3.scaleDiverging](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleDiverging) - create a diverging scale. +* [*diverging*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_diverging) - compute the range value corresponding to an input value. +* [*diverging*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#diverging_domain) - set the input domain. +* [*diverging*.clamp](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#diverging_clamp) - enable clamping to the domain or range. +* [*diverging*.interpolator](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#diverging_interpolator) - set the scale’s output interpolator. +* [*diverging*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#diverging_range) - set the output range. +* [*diverging*.rangeRound](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#diverging_rangeRound) - set the output range and enable rounding. +* [*diverging*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#diverging_copy) - create a copy of this scale. +* [*diverging*.unknown](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#diverging_unknown) - set the output value for unknown inputs. +* [d3.scaleDivergingLog](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleDivergingLog) - create a diverging logarithmic scale. +* [d3.scaleDivergingPow](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleDivergingPow) - create a diverging power scale. +* [d3.scaleDivergingSqrt](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleDivergingSqrt) - create a diverging power scale with exponent 0.5. +* [d3.scaleDivergingSymlog](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleDivergingSymlog) - create a diverging symmetric logarithmic scale. + +### [Quantize Scales](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize-scales) + +Map a continuous, quantitative domain to a discrete range. + +* [d3.scaleQuantize](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleQuantize) - create a uniform quantizing linear scale. +* [*quantize*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_quantize) - compute the range value corresponding to a given domain value. +* [*quantize*.invertExtent](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize_invertExtent) - compute the domain values corresponding to a given range value. +* [*quantize*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize_domain) - set the input domain. +* [*quantize*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize_range) - set the output range. +* [*quantize*.ticks](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize_ticks) - compute representative values from the domain. +* [*quantize*.tickFormat](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize_tickFormat) - format ticks for human consumption. +* [*quantize*.nice](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize_nice) - extend the domain to nice round numbers. +* [*quantize*.thresholds](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize_thresholds) - return the array of computed thresholds within the domain. +* [*quantize*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantize_copy) - create a copy of this scale. +* [d3.scaleQuantile](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleQuantile) - create a quantile quantizing linear scale. +* [*quantile*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_quantile) - compute the range value corresponding to a given domain value. +* [*quantile*.invertExtent](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantile_invertExtent) - compute the domain values corresponding to a given range value. +* [*quantile*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantile_domain) - set the input domain. +* [*quantile*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantile_range) - set the output range. +* [*quantile*.quantiles](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantile_quantiles) - get the quantile thresholds. +* [*quantile*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#quantile_copy) - create a copy of this scale. +* [d3.scaleThreshold](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleThreshold) - create an arbitrary quantizing linear scale. +* [*threshold*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_threshold) - compute the range value corresponding to a given domain value. +* [*threshold*.invertExtent](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#threshold_invertExtent) - compute the domain values corresponding to a given range value. +* [*threshold*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#threshold_domain) - set the input domain. +* [*threshold*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#threshold_range) - set the output range. +* [*threshold*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#threshold_copy) - create a copy of this scale. + +### [Ordinal Scales](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#ordinal-scales) + +Map a discrete domain to a discrete range. + +* [d3.scaleOrdinal](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleOrdinal) - create an ordinal scale. +* [*ordinal*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_ordinal) - compute the range value corresponding to a given domain value. +* [*ordinal*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#ordinal_domain) - set the input domain. +* [*ordinal*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#ordinal_range) - set the output range. +* [*ordinal*.unknown](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#ordinal_unknown) - set the output value for unknown inputs. +* [*ordinal*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#ordinal_copy) - create a copy of this scale. +* [d3.scaleImplicit](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleImplicit) - a special unknown value for implicit domains. +* [d3.scaleBand](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scaleBand) - create an ordinal band scale. +* [*band*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_band) - compute the band start corresponding to a given domain value. +* [*band*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_domain) - set the input domain. +* [*band*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_range) - set the output range. +* [*band*.rangeRound](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_rangeRound) - set the output range and enable rounding. +* [*band*.round](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_round) - enable rounding. +* [*band*.paddingInner](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_paddingInner) - set padding between bands. +* [*band*.paddingOuter](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_paddingOuter) - set padding outside the first and last bands. +* [*band*.padding](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_padding) - set padding outside and between bands. +* [*band*.align](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_align) - set band alignment, if there is extra space. +* [*band*.bandwidth](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_bandwidth) - get the width of each band. +* [*band*.step](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_step) - get the distance between the starts of adjacent bands. +* [*band*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#band_copy) - create a copy of this scale. +* [d3.scalePoint](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#scalePoint) - create an ordinal point scale. +* [*point*](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#_point) - compute the point corresponding to a given domain value. +* [*point*.domain](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_domain) - set the input domain. +* [*point*.range](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_range) - set the output range. +* [*point*.rangeRound](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_rangeRound) - set the output range and enable rounding. +* [*point*.round](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_round) - enable rounding. +* [*point*.padding](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_padding) - set padding outside the first and last point. +* [*point*.align](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_align) - set point alignment, if there is extra space. +* [*point*.bandwidth](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_bandwidth) - returns zero. +* [*point*.step](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_step) - get the distance between the starts of adjacent points. +* [*point*.copy](https://github.com/d3/d3-scale/blob/v3.3.0/README.md#point_copy) - create a copy of this scale. + +## [Selections (d3-selection)](https://github.com/d3/d3-selection/tree/v2.0.0) + +Transform the DOM by selecting elements and joining to data. + +### [Selecting Elements](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selecting-elements) + +* [d3.selection](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection) - select the root document element. +* [d3.select](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#select) - select an element from the document. +* [d3.selectAll](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selectAll) - select multiple elements from the document. +* [*selection*.select](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_select) - select a descendant element for each selected element. +* [*selection*.selectAll](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_selectAll) - select multiple descendants for each selected element. +* [*selection*.filter](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_filter) - filter elements based on data. +* [*selection*.merge](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_merge) - merge this selection with another. +* [*selection*.selectChild](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_selectChild) - select a child element for each selected element. +* [*selection*.selectChildren](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_selectChildren) - select the children elements for each selected element. +* [*selection*.selection](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_selection) - return the selection. +* [d3.matcher](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#matcher) - test whether an element matches a selector. +* [d3.selector](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selector) - select an element. +* [d3.selectorAll](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selectorAll) - select elements. +* [d3.window](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#window) - get a node’s owner window. +* [d3.style](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#style) - get a node’s current style value. + +### [Modifying Elements](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#modifying-elements) + +* [*selection*.attr](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_attr) - get or set an attribute. +* [*selection*.classed](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_classed) - get, add or remove CSS classes. +* [*selection*.style](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_style) - get or set a style property. +* [*selection*.property](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_property) - get or set a (raw) property. +* [*selection*.text](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_text) - get or set the text content. +* [*selection*.html](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_html) - get or set the inner HTML. +* [*selection*.append](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_append) - create, append and select new elements. +* [*selection*.insert](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_insert) - create, insert and select new elements. +* [*selection*.remove](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_remove) - remove elements from the document. +* [*selection*.clone](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_clone) - insert clones of selected elements. +* [*selection*.sort](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_sort) - sort elements in the document based on data. +* [*selection*.order](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_order) - reorders elements in the document to match the selection. +* [*selection*.raise](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_raise) - reorders each element as the last child of its parent. +* [*selection*.lower](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_lower) - reorders each element as the first child of its parent. +* [d3.create](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#create) - create and select a detached element. +* [d3.creator](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#creator) - create an element by name. + +### [Joining Data](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#joining-data) + +* [*selection*.data](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_data) - bind elements to data. +* [*selection*.join](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_join) - enter, update or exit elements based on data. +* [*selection*.enter](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_enter) - get the enter selection (data missing elements). +* [*selection*.exit](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_exit) - get the exit selection (elements missing data). +* [*selection*.datum](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_datum) - get or set element data (without joining). + +### [Handling Events](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#handling-events) + +* [*selection*.on](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_on) - add or remove event listeners. +* [*selection*.dispatch](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_dispatch) - dispatch a custom event. +* [d3.pointer](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#pointer) - get the pointer’s position of an event. +* [d3.pointers](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#pointers) - get the pointers’ positions of an event. + +### [Control Flow](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#control-flow) + +* [*selection*.each](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_each) - call a function for each element. +* [*selection*.call](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_call) - call a function with this selection. +* [*selection*.empty](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_empty) - returns true if this selection is empty. +* [*selection*.nodes](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_nodes) - returns an array of all selected elements. +* [*selection*.node](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_node) - returns the first (non-null) element. +* [*selection*.size](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_size) - returns the count of elements. +* [*selection*[Symbol.iterator]](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_iterator) - iterate over the selection’s nodes. + +### [Local Variables](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#local-variables) + +* [d3.local](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#local) - declares a new local variable. +* [*local*.set](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#local_set) - set a local variable’s value. +* [*local*.get](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#local_get) - get a local variable’s value. +* [*local*.remove](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#local_remove) - delete a local variable. +* [*local*.toString](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#local_toString) - get the property identifier of a local variable. + +### [Namespaces](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#namespaces) + +* [d3.namespace](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#namespace) - qualify a prefixed XML name, such as “xlink:href”. +* [d3.namespaces](https://github.com/d3/d3-selection/blob/v2.0.0/README.md#namespaces) - the built-in XML namespaces. + +## [Shapes (d3-shape)](https://github.com/d3/d3-shape/tree/v2.1.0) + +Graphical primitives for visualization. + +### [Arcs](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arcs) + +Circular or annular sectors, as in a pie or donut chart. + +* [d3.arc](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc) - create a new arc generator. +* [*arc*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_arc) - generate an arc for the given datum. +* [*arc*.centroid](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_centroid) - compute an arc’s midpoint. +* [*arc*.innerRadius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_innerRadius) - set the inner radius. +* [*arc*.outerRadius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_outerRadius) - set the outer radius. +* [*arc*.cornerRadius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_cornerRadius) - set the corner radius, for rounded corners. +* [*arc*.startAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_startAngle) - set the start angle. +* [*arc*.endAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_endAngle) - set the end angle. +* [*arc*.padAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_padAngle) - set the angle between adjacent arcs, for padded arcs. +* [*arc*.padRadius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_padRadius) - set the radius at which to linearize padding. +* [*arc*.context](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#arc_context) - set the rendering context. + +### [Pies](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pies) + +Compute the necessary angles to represent a tabular dataset as a pie or donut chart. + +* [d3.pie](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pie) - create a new pie generator. +* [*pie*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_pie) - compute the arc angles for the given dataset. +* [*pie*.value](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pie_value) - set the value accessor. +* [*pie*.sort](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pie_sort) - set the sort order comparator. +* [*pie*.sortValues](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pie_sortValues) - set the sort order comparator. +* [*pie*.startAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pie_startAngle) - set the overall start angle. +* [*pie*.endAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pie_endAngle) - set the overall end angle. +* [*pie*.padAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pie_padAngle) - set the pad angle between adjacent arcs. + +### [Lines](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#lines) + +A spline or polyline, as in a line chart. + +* [d3.line](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#line) - create a new line generator. +* [*line*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_line) - generate a line for the given dataset. +* [*line*.x](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#line_x) - set the *x* accessor. +* [*line*.y](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#line_y) - set the *y* accessor. +* [*line*.defined](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#line_defined) - set the defined accessor. +* [*line*.curve](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#line_curve) - set the curve interpolator. +* [*line*.context](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#line_context) - set the rendering context. +* [d3.lineRadial](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#lineRadial) - create a new radial line generator. +* [*lineRadial*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_lineRadial) - generate a line for the given dataset. +* [*lineRadial*.angle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#lineRadial_angle) - set the angle accessor. +* [*lineRadial*.radius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#lineRadial_radius) - set the radius accessor. +* [*lineRadial*.defined](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#lineRadial_defined) - set the defined accessor. +* [*lineRadial*.curve](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#lineRadial_curve) - set the curve interpolator. +* [*lineRadial*.context](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#lineRadial_context) - set the rendering context. + +### [Areas](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areas) + +An area, defined by a bounding topline and baseline, as in an area chart. + +* [d3.area](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area) - create a new area generator. +* [*area*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_area) - generate an area for the given dataset. +* [*area*.x](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_x) - set the *x0* and *x1* accessors. +* [*area*.x0](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_x0) - set the baseline *x* accessor. +* [*area*.x1](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_x1) - set the topline *x* accessor. +* [*area*.y](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_y) - set the *y0* and *y1* accessors. +* [*area*.y0](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_y0) - set the baseline *y* accessor. +* [*area*.y1](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_y1) - set the topline *y* accessor. +* [*area*.defined](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_defined) - set the defined accessor. +* [*area*.curve](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_curve) - set the curve interpolator. +* [*area*.context](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_context) - set the rendering context. +* [*area*.lineX0](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_lineX0) - derive a line for the left edge of an area. +* [*area*.lineY0](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_lineY0) - derive a line for the top edge of an area. +* [*area*.lineX1](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_lineX1) - derive a line for the right edge of an area. +* [*area*.lineY1](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#area_lineY1) - derive a line for the bottom edge of an area. +* [d3.areaRadial](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial) - create a new radial area generator. +* [*areaRadial*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_areaRadial) - generate an area for the given dataset. +* [*areaRadial*.angle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_angle) - set the start and end angle accessors. +* [*areaRadial*.startAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_startAngle) - set the start angle accessor. +* [*areaRadial*.endAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_endAngle) - set the end angle accessor. +* [*areaRadial*.radius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_radius) - set the inner and outer radius accessors. +* [*areaRadial*.innerRadius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_innerRadius) - set the inner radius accessor. +* [*areaRadial*.outerRadius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_outerRadius) - set the outer radius accessor. +* [*areaRadial*.defined](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_defined) - set the defined accessor. +* [*areaRadial*.curve](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_curve) - set the curve interpolator. +* [*areaRadial*.context](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_context) - set the rendering context. +* [*areaRadial*.lineStartAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_lineStartAngle) - derive a line for the start edge of an area. +* [*areaRadial*.lineInnerRadius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_lineInnerRadius) - derive a line for the inner edge of an area. +* [*areaRadial*.lineEndAngle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_lineEndAngle) - derive a line for the end edge of an area. +* [*areaRadial*.lineOuterRadius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#areaRadial_lineOuterRadius) - derive a line for the outer edge of an area. + +### [Curves](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curves) + +Interpolate between points to produce a continuous shape. + +* [d3.curveBasis](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveBasis) - a cubic basis spline, repeating the end points. +* [d3.curveBasisClosed](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveBasisClosed) - a closed cubic basis spline. +* [d3.curveBasisOpen](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveBasisOpen) - a cubic basis spline. +* [d3.curveBundle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveBundle) - a straightened cubic basis spline. +* [*bundle*.beta](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveBundle_beta) - set the bundle tension *beta*. +* [d3.curveBumpX](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveBumpX) - a cubic Bézier spline with horizontal tangents. +* [d3.curveBumpY](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveBumpY) - a cubic Bézier spline with vertical tangents. +* [d3.curveCardinal](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveCardinal) - a cubic cardinal spline, with one-sided difference at each end. +* [d3.curveCardinalClosed](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveCardinalClosed) - a closed cubic cardinal spline. +* [d3.curveCardinalOpen](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveCardinalOpen) - a cubic cardinal spline. +* [*cardinal*.tension](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveCardinal_tension) - set the cardinal spline tension. +* [d3.curveCatmullRom](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveCatmullRom) - a cubic Catmull–Rom spline, with one-sided difference at each end. +* [d3.curveCatmullRomClosed](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveCatmullRomClosed) - a closed cubic Catmull–Rom spline. +* [d3.curveCatmullRomOpen](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveCatmullRomOpen) - a cubic Catmull–Rom spline. +* [*catmullRom*.alpha](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveCatmullRom_alpha) - set the Catmull–Rom parameter *alpha*. +* [d3.curveLinear](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveLinear) - a polyline. +* [d3.curveLinearClosed](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveLinearClosed) - a closed polyline. +* [d3.curveMonotoneX](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveMonotoneX) - a cubic spline that, given monotonicity in *x*, preserves it in *y*. +* [d3.curveMonotoneY](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveMonotoneY) - a cubic spline that, given monotonicity in *y*, preserves it in *x*. +* [d3.curveNatural](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveNatural) - a natural cubic spline. +* [d3.curveStep](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveStep) - a piecewise constant function. +* [d3.curveStepAfter](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveStepAfter) - a piecewise constant function. +* [d3.curveStepBefore](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curveStepBefore) - a piecewise constant function. +* [*curve*.areaStart](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curve_areaStart) - start a new area segment. +* [*curve*.areaEnd](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curve_areaEnd) - end the current area segment. +* [*curve*.lineStart](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curve_lineStart) - start a new line segment. +* [*curve*.lineEnd](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curve_lineEnd) - end the current line segment. +* [*curve*.point](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#curve_point) - add a point to the current line segment. + +### [Links](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#links) + +A smooth cubic Bézier curve from a source to a target. + +* [d3.linkVertical](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#linkVertical) - create a new vertical link generator. +* [d3.linkHorizontal](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#linkHorizontal) - create a new horizontal link generator. +* [*link*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_link) - generate a link. +* [*link*.source](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#link_source) - set the source accessor. +* [*link*.target](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#link_target) - set the target accessor. +* [*link*.x](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#link_x) - set the point *x*-accessor. +* [*link*.y](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#link_y) - set the point *y*-accessor. +* [*link*.context](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#link_context) - set the rendering context. +* [d3.linkRadial](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#linkRadial) - create a new radial link generator. +* [*linkRadial*.angle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#linkRadial_angle) - set the point *angle* accessor. +* [*linkRadial*.radius](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#linkRadial_radius) - set the point *radius* accessor. + +### [Symbols](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbols) + +A categorical shape encoding, as in a scatterplot. + +* [d3.symbol](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbol) - create a new symbol generator. +* [*symbol*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_symbol) - generate a symbol for the given datum. +* [*symbol*.type](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbol_type) - set the symbol type. +* [*symbol*.size](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbol_size) - set the size of the symbol in square pixels. +* [*symbol*.context](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbol_context) - set the rendering context. +* [d3.symbols](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbols) - the array of built-in symbol types. +* [d3.symbolCircle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbolCircle) - a circle. +* [d3.symbolCross](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbolCross) - a Greek cross with arms of equal length. +* [d3.symbolDiamond](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbolDiamond) - a rhombus. +* [d3.symbolSquare](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbolSquare) - a square. +* [d3.symbolStar](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbolStar) - a pentagonal star (pentagram). +* [d3.symbolTriangle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbolTriangle) - an up-pointing triangle. +* [d3.symbolWye](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbolWye) - a Y shape. +* [d3.pointRadial](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#pointRadial) - relative coordinates of a point given an angle and radius. +* [*symbolType*.draw](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#symbolType_draw) - draw this symbol to the given context. + +### [Stacks](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stacks) + +Stack shapes, placing one adjacent to another, as in a stacked bar chart. + +* [d3.stack](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stack) - create a new stack generator. +* [*stack*](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#_stack) - generate a stack for the given dataset. +* [*stack*.keys](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stack_keys) - set the keys accessor. +* [*stack*.value](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stack_value) - set the value accessor. +* [*stack*.order](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stack_order) - set the order accessor. +* [*stack*.offset](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stack_offset) - set the offset accessor. +* [d3.stackOrderAppearance](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOrderAppearance) - put the earliest series on bottom. +* [d3.stackOrderAscending](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOrderAscending) - put the smallest series on bottom. +* [d3.stackOrderDescending](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOrderDescending) - put the largest series on bottom. +* [d3.stackOrderInsideOut](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOrderInsideOut) - put earlier series in the middle. +* [d3.stackOrderNone](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOrderNone) - use the given series order. +* [d3.stackOrderReverse](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOrderReverse) - use the reverse of the given series order. +* [d3.stackOffsetExpand](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOffsetExpand) - normalize the baseline to zero and topline to one. +* [d3.stackOffsetDiverging](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOffsetDiverging) - positive above zero; negative below zero. +* [d3.stackOffsetNone](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOffsetNone) - apply a zero baseline. +* [d3.stackOffsetSilhouette](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOffsetSilhouette) - center the streamgraph around zero. +* [d3.stackOffsetWiggle](https://github.com/d3/d3-shape/blob/v2.1.0/README.md#stackOffsetWiggle) - minimize streamgraph wiggling. + +## [Time Formats (d3-time-format)](https://github.com/d3/d3-time-format/tree/v3.0.0) + +Parse and format times, inspired by strptime and strftime. + +* [d3.timeFormat](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#timeFormat) - alias for *locale*.format on the default locale. +* [d3.timeParse](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#timeParse) - alias for *locale*.parse on the default locale. +* [d3.utcFormat](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#utcFormat) - alias for *locale*.utcFormat on the default locale. +* [d3.utcParse](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#utcParse) - alias for *locale*.utcParse on the default locale. +* [d3.isoFormat](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#isoFormat) - an ISO 8601 UTC formatter. +* [d3.isoParse](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#isoParse) - an ISO 8601 UTC parser. +* [*locale*.format](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#locale_format) - create a time formatter. +* [*locale*.parse](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#locale_parse) - create a time parser. +* [*locale*.utcFormat](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#locale_utcFormat) - create a UTC formatter. +* [*locale*.utcParse](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#locale_utcParse) - create a UTC parser. +* [d3.timeFormatLocale](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#timeFormatLocale) - define a custom locale. +* [d3.timeFormatDefaultLocale](https://github.com/d3/d3-time-format/blob/v3.0.0/README.md#timeFormatDefaultLocale) - define the default locale. + +## [Time Intervals (d3-time)](https://github.com/d3/d3-time/tree/v2.1.0) + +A calculator for humanity’s peculiar conventions of time. + +* [d3.timeInterval](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeInterval) - implement a new custom time interval. +* [*interval*](https://github.com/d3/d3-time/blob/v2.1.0/README.md#_interval) - alias for *interval*.floor. +* [*interval*.floor](https://github.com/d3/d3-time/blob/v2.1.0/README.md#interval_floor) - round down to the nearest boundary. +* [*interval*.round](https://github.com/d3/d3-time/blob/v2.1.0/README.md#interval_round) - round to the nearest boundary. +* [*interval*.ceil](https://github.com/d3/d3-time/blob/v2.1.0/README.md#interval_ceil) - round up to the nearest boundary. +* [*interval*.offset](https://github.com/d3/d3-time/blob/v2.1.0/README.md#interval_offset) - offset a date by some number of intervals. +* [*interval*.range](https://github.com/d3/d3-time/blob/v2.1.0/README.md#interval_range) - generate a range of dates at interval boundaries. +* [*interval*.filter](https://github.com/d3/d3-time/blob/v2.1.0/README.md#interval_filter) - create a filtered subset of this interval. +* [*interval*.every](https://github.com/d3/d3-time/blob/v2.1.0/README.md#interval_every) - create a filtered subset of this interval. +* [*interval*.count](https://github.com/d3/d3-time/blob/v2.1.0/README.md#interval_count) - count interval boundaries between two dates. +* [d3.timeMillisecond](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMillisecond), [d3.utcMillisecond](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMillisecond) - the millisecond interval. +* [d3.timeMilliseconds](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMillisecond), [d3.utcMilliseconds](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMillisecond) - aliases for millisecond.range. +* [d3.timeSecond](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSecond), [d3.utcSecond](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSecond) - the second interval. +* [d3.timeSeconds](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSecond), [d3.utcSeconds](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSecond) - aliases for second.range. +* [d3.timeMinute](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMinute), [d3.utcMinute](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMinute) - the minute interval. +* [d3.timeMinutes](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMinute), [d3.utcMinutes](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMinute) - aliases for minute.range. +* [d3.timeHour](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeHour), [d3.utcHour](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeHour) - the hour interval. +* [d3.timeHours](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeHour), [d3.utcHours](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeHour) - aliases for hour.range. +* [d3.timeDay](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeDay), [d3.utcDay](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeDay) - the day interval. +* [d3.timeDays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeDay), [d3.utcDays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeDay) - aliases for day.range. +* [d3.timeWeek](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeWeek), [d3.utcWeek](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeWeek) - aliases for sunday. +* [d3.timeWeeks](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeWeek), [d3.utcWeeks](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeWeek) - aliases for week.range. +* [d3.timeSunday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSunday), [d3.utcSunday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSunday) - the week interval, starting on Sunday. +* [d3.timeSundays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSunday), [d3.utcSundays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSunday) - aliases for sunday.range. +* [d3.timeMonday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMonday), [d3.utcMonday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMonday) - the week interval, starting on Monday. +* [d3.timeMondays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMonday), [d3.utcMondays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMonday) - aliases for monday.range. +* [d3.timeTuesday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeTuesday), [d3.utcTuesday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeTuesday) - the week interval, starting on Tuesday. +* [d3.timeTuesdays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeTuesday), [d3.utcTuesdays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeTuesday) - aliases for tuesday.range. +* [d3.timeWednesday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeWednesday), [d3.utcWednesday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeWednesday) - the week interval, starting on Wednesday. +* [d3.timeWednesdays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeWednesday), [d3.utcWednesdays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeWednesday) - aliases for wednesday.range. +* [d3.timeThursday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeThursday), [d3.utcThursday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeThursday) - the week interval, starting on Thursday. +* [d3.timeThursdays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeThursday), [d3.utcThursdays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeThursday) - aliases for thursday.range. +* [d3.timeFriday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeFriday), [d3.utcFriday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeFriday) - the week interval, starting on Friday. +* [d3.timeFridays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeFriday), [d3.utcFridays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeFriday) - aliases for friday.range. +* [d3.timeSaturday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSaturday), [d3.utcSaturday](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSaturday) - the week interval, starting on Saturday. +* [d3.timeSaturdays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSaturday), [d3.utcSaturdays](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeSaturday) - aliases for saturday.range. +* [d3.timeMonth](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMonth), [d3.utcMonth](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMonth) - the month interval. +* [d3.timeMonths](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMonth), [d3.utcMonths](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeMonth) - aliases for month.range. +* [d3.timeYear](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeYear), [d3.utcYear](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeYear) - the year interval. +* [d3.timeYears](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeYear), [d3.utcYears](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeYear) - aliases for year.range. +* [d3.timeTicks](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeTicks), [d3.utcTicks](https://github.com/d3/d3-time/blob/v2.1.0/README.md#utcTicks) - +* [d3.timeTickInterval](https://github.com/d3/d3-time/blob/v2.1.0/README.md#timeTickInterval), [d3.utcTickInterval](https://github.com/d3/d3-time/blob/v2.1.0/README.md#utcTickInterval) - + +## [Timers (d3-timer)](https://github.com/d3/d3-timer/tree/v2.0.0) + +An efficient queue for managing thousands of concurrent animations. + +* [d3.now](https://github.com/d3/d3-timer/blob/v2.0.0/README.md#now) - get the current high-resolution time. +* [d3.timer](https://github.com/d3/d3-timer/blob/v2.0.0/README.md#timer) - schedule a new timer. +* [*timer*.restart](https://github.com/d3/d3-timer/blob/v2.0.0/README.md#timer_restart) - reset the timer’s start time and callback. +* [*timer*.stop](https://github.com/d3/d3-timer/blob/v2.0.0/README.md#timer_stop) - stop the timer. +* [d3.timerFlush](https://github.com/d3/d3-timer/blob/v2.0.0/README.md#timerFlush) - immediately execute any eligible timers. +* [d3.timeout](https://github.com/d3/d3-timer/blob/v2.0.0/README.md#timeout) - schedule a timer that stops on its first callback. +* [d3.interval](https://github.com/d3/d3-timer/blob/v2.0.0/README.md#interval) - schedule a timer that is called with a configurable period. + +## [Transitions (d3-transition)](https://github.com/d3/d3-transition/tree/v2.0.0) + +Animated transitions for [selections](#selections). + +* [*selection*.transition](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#selection_transition) - schedule a transition for the selected elements. +* [*selection*.interrupt](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#selection_interrupt) - interrupt and cancel transitions on the selected elements. +* [d3.interrupt](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#interrupt) - interrupt the active transition for a given node. +* [d3.transition](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition) - schedule a transition on the root document element. +* [*transition*.select](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_select) - schedule a transition on the selected elements. +* [*transition*.selectAll](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_selectAll) - schedule a transition on the selected elements. +* [*transition*.filter](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_filter) - filter elements based on data. +* [*transition*.merge](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_merge) - merge this transition with another. +* [*transition*.transition](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_transition) - schedule a new transition following this one. +* [*transition*.selection](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_selection) - returns a selection for this transition. +* [d3.active](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#active) - select the active transition for a given node. +* [*transition*.attr](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_attr) - tween the given attribute using the default interpolator. +* [*transition*.attrTween](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_attrTween) - tween the given attribute using a custom interpolator. +* [*transition*.style](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_style) - tween the given style property using the default interpolator. +* [*transition*.styleTween](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_styleTween) - tween the given style property using a custom interpolator. +* [*transition*.text](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_text) - set the text content when the transition starts. +* [*transition*.textTween](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_textTween) - tween the text using a custom interpolator. +* [*transition*.remove](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_remove) - remove the selected elements when the transition ends. +* [*transition*.tween](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_tween) - run custom code during the transition. +* [*transition*.delay](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_delay) - specify per-element delay in milliseconds. +* [*transition*.duration](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_duration) - specify per-element duration in milliseconds. +* [*transition*.ease](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_ease) - specify the easing function. +* [*transition*.easeVarying](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_easeVarying) - specify an easing function factory. +* [*transition*.end](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_end) - a promise that resolves when a transition ends. +* [*transition*.on](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_on) - await the end of a transition. +* [*transition*.each](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_each) - call a function for each element. +* [*transition*.call](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_call) - call a function with this transition. +* [*transition*.empty](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_empty) - returns true if this transition is empty. +* [*transition*.nodes](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_nodes) - returns an array of all selected elements. +* [*transition*.node](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_node) - returns the first (non-null) element. +* [*transition*.size](https://github.com/d3/d3-transition/blob/v2.0.0/README.md#transition_size) - returns the count of elements. + +## [Zooming (d3-zoom)](https://github.com/d3/d3-zoom/tree/v2.0.0) + +Pan and zoom SVG, HTML or Canvas using mouse or touch input. + +* [d3.zoom](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom) - create a zoom behavior. +* [*zoom*](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#_zoom) - apply the zoom behavior to the selected elements. +* [*zoom*.transform](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_transform) - change the transform for the selected elements. +* [*zoom*.translateBy](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_translateBy) - translate the transform for the selected elements. +* [*zoom*.translateTo](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_translateTo) - translate the transform for the selected elements. +* [*zoom*.scaleBy](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_scaleBy) - scale the transform for the selected elements. +* [*zoom*.scaleTo](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_scaleTo) - scale the transform for the selected elements. +* [*zoom*.constrain](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_constrain) - override the transform constraint logic. +* [*zoom*.filter](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_filter) - control which input events initiate zooming. +* [*zoom*.touchable](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_touchable) - set the touch support detector. +* [*zoom*.wheelDelta](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_wheelDelta) - override scaling for wheel events. +* [*zoom*.extent](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_extent) - set the extent of the viewport. +* [*zoom*.scaleExtent](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_scaleExtent) - set the allowed scale range. +* [*zoom*.translateExtent](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_translateExtent) - set the extent of the zoomable world. +* [*zoom*.clickDistance](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_clickDistance) - set the click distance threshold. +* [*zoom*.tapDistance](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_tapDistance) - set the tap distance threshold. +* [*zoom*.duration](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_duration) - set the duration of zoom transitions. +* [*zoom*.interpolate](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_interpolate) - control the interpolation of zoom transitions. +* [*zoom*.on](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoom_on) - listen for zoom events. +* [d3.zoomTransform](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoomTransform) - get the zoom transform for a given element. +* [*transform*.scale](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_scale) - scale a transform by the specified amount. +* [*transform*.translate](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_translate) - translate a transform by the specified amount. +* [*transform*.apply](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_apply) - apply the transform to the given point. +* [*transform*.applyX](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_applyX) - apply the transform to the given *x*-coordinate. +* [*transform*.applyY](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_applyY) - apply the transform to the given *y*-coordinate. +* [*transform*.invert](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_invert) - unapply the transform to the given point. +* [*transform*.invertX](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_invertX) - unapply the transform to the given *x*-coordinate. +* [*transform*.invertY](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_invertY) - unapply the transform to the given *y*-coordinate. +* [*transform*.rescaleX](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_rescaleX) - apply the transform to an *x*-scale’s domain. +* [*transform*.rescaleY](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_rescaleY) - apply the transform to a *y*-scale’s domain. +* [*transform*.toString](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#transform_toString) - format the transform as an SVG transform string. +* [d3.zoomIdentity](https://github.com/d3/d3-zoom/blob/v2.0.0/README.md#zoomIdentity) - the identity transform. diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 00000000000000..b55924450a5e65 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,1643 @@ +# Changes in D3 6.0 + +[Released August 26, 2020.](https://github.com/d3/d3/releases/tag/v6.0.0) + +*This document covers only major changes. For minor and patch changes, please see the [release notes](https://github.com/d3/d3/releases).* + +D3 now **uses native collections** (Map and Set) and **accepts iterables**. [d3.group and d3.rollup](https://observablehq.com/@d3/d3-group) are powerful new aggregation functions that replace d3.nest and work great [with d3-hierarchy](https://observablehq.com/d/9a453665f405eebf) and d3-selection. There are lots of new helpers in d3-array, too, such as [d3.greatest](https://observablehq.com/@d3/d3-least), [d3.quickselect](https://observablehq.com/@d3/d3-quickselect), and [d3.fsum](https://observablehq.com/@d3/d3-fsum). + +D3 now **passes events directly to listeners**, replacing the d3.event global and bringing D3 inline with vanilla JavaScript and most other frameworks. + +**d3-delaunay** (based on Vladimir Agafonkin’s excellent [Delaunator](https://github.com/mapbox/delaunator)) replaces d3-voronoi, offering dramatic improvements to performance, robustness, and [search](https://observablehq.com/@d3/delaunay-find). And there’s a new [d3-geo-voronoi](https://github.com/Fil/d3-geo-voronoi) for spherical (geographical) data! **d3-random** is [greatly expanded](https://github.com/d3/d3-random/blob/master/README.md) and includes a fast [linear congruential generator](https://observablehq.com/@d3/d3-randomlcg) for seeded randomness. **d3-chord** has new layouts for [directed](https://observablehq.com/@d3/directed-chord-diagram) and transposed chord diagrams. **d3-scale** adds a new [radial scale](https://observablehq.com/@d3/radial-stacked-bar-chart-ii) type. + +… and a variety of other small enhancements. [More than 450 examples](https://observablehq.com/@d3/gallery) have been updated to D3 6.0! + +### d3-array + +* Accept iterables. +* Add [d3.group](https://github.com/d3/d3-array/blob/master/README.md#group). +* Add [d3.groups](https://github.com/d3/d3-array/blob/master/README.md#groups). +* Add [d3.index](https://github.com/d3/d3-array/blob/master/README.md#index). +* Add [d3.indexes](https://github.com/d3/d3-array/blob/master/README.md#indexes). +* Add [d3.rollup](https://github.com/d3/d3-array/blob/master/README.md#rollup). +* Add [d3.rollups](https://github.com/d3/d3-array/blob/master/README.md#rollups). +* Add [d3.maxIndex](https://github.com/d3/d3-array/blob/master/README.md#maxIndex). +* Add [d3.minIndex](https://github.com/d3/d3-array/blob/master/README.md#minIndex). +* Add [d3.greatest](https://github.com/d3/d3-array/blob/master/README.md#greatest). +* Add [d3.greatestIndex](https://github.com/d3/d3-array/blob/master/README.md#greatestIndex). +* Add [d3.least](https://github.com/d3/d3-array/blob/master/README.md#least). +* Add [d3.leastIndex](https://github.com/d3/d3-array/blob/master/README.md#leastIndex). +* Add [d3.bin](https://github.com/d3/d3-array/blob/master/README.md#bin). +* Add [d3.count](https://github.com/d3/d3-array/blob/master/README.md#count). +* Add [d3.cumsum](https://github.com/d3/d3-array/blob/master/README.md#cumsum). +* Add [d3.fsum](https://github.com/d3/d3-array/blob/master/README.md#fsum). +* Add [d3.Adder](https://github.com/d3/d3-array/blob/master/README.md#Adder). +* Add [d3.quantileSorted](https://github.com/d3/d3-array/blob/master/README.md#quantileSorted). +* Add [d3.quickselect](https://github.com/d3/d3-array/blob/master/README.md#quickselect). +* Add [*bisector*.center](https://github.com/d3/d3-array/blob/master/README.md#bisector_center). +* Allow more than two iterables for [d3.cross](https://github.com/d3/d3-array/blob/master/README.md#cross). +* Accept non-sorted input with [d3.quantile](https://github.com/d3/d3-array/blob/master/README.md#quantile). +* Fix a *array*.sort bug in Safari. +* Fix bin thresholds to ignore NaN input. +* Fix [d3.ticks](https://github.com/d3/d3-array/blob/master/README.md#ticks) to not return ticks outside the domain. +* Improve the performance of [d3.median](https://github.com/d3/d3-array/blob/master/README.md#median). + +See https://observablehq.com/@d3/d3-array-2-0 for details. + +### d3-brush + +* Add [*event*.mode](https://github.com/d3/d3-brush/blob/master/README.md#brush-events). +* Change [*brush*.on](https://github.com/d3/d3-brush/blob/master/README.md#brush_on) to pass the *event* directly to listeners. +* Improve multitouch (two-touch) interaction. + +### d3-chord + +* Add [d3.chordDirected](https://github.com/d3/d3-chord/blob/master/README.md#chordDirected). +* Add [d3.chordTranspose](https://github.com/d3/d3-chord/blob/master/README.md#chordTranspose). +* Add [d3.ribbonArrow](https://github.com/d3/d3-chord/blob/master/README.md#ribbonArrow). +* Add [*ribbon*.padAngle](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_padAngle). +* Add [*ribbon*.sourceRadius](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_sourceRadius). +* Add [*ribbon*.targetRadius](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_targetRadius). + +### d3-delaunay + +* Add [d3.Delaunay](https://github.com/d3/d3-delaunay/blob/master/README.md). + +### d3-drag + +* Change [*drag*.on](https://github.com/d3/d3-drag/blob/master/README.md#drag_on) to pass the *event* directly to listeners. + +### d3-force + +* Add *iterations* argument to [*simulation*.tick](https://github.com/d3/d3-force/blob/master/README.md#simulation_tick). +* Add [*forceCenter*.strength](https://github.com/d3/d3-force/blob/master/README.md#center_strength). +* Add [*forceSimulation*.randomSource](https://github.com/d3/d3-force/blob/master/README.md#simulation_randomSource). +* All built-in forces are now fully deterministic (including “jiggling” coincident nodes). +* Improve the default phyllotaxis layout slightly by offsetting by one half-radius. +* Improve the error message when a link references an unknown node. +* [*force*.initialize](https://github.com/d3/d3-force/blob/master/README.md#force_initialize) is now passed a random source. +* Fix bug when initializing nodes with fixed positions. + +### d3-format + +* Change the default minus sign to the minus sign (−) instead of hyphen-minus (-). +* Fix decimal `d` formatting of numbers greater than or equal to 1e21. + +### d3-geo + +* Fix clipping of some degenerate polygons. + +### d3-hierarchy + +* Accept iterables. +* Add [*node*[Symbol.iterator]](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_iterator); hierarchies are now iterable. +* Add [*node*.find](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_find). +* Change [*node*.each](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_each) to pass the traversal index. +* Change [*node*.eachAfter](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_eachAfter) to pass the traversal index. +* Change [*node*.eachBefore](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_eachBefore) to pass the traversal index. +* Fix [d3.packSiblings](https://github.com/d3/d3-hierarchy/blob/master/README.md#packSiblings) for huge circles. +* Fix divide-by-zero bug in [d3.treemapBinary](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapBinary). +* Fix divide-by-zero bug in [d3.treemapResquarify](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapResquarify). + +### d3-interpolate + +* Add [*interpolateZoom*.rho](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateZoom_rho). (#25) +* Allow [d3.piecewise](https://github.com/d3/d3-interpolate/blob/master/README.md#piecewise) to default to using d3.interpolate. #90 +* Change [d3.interpolateTransformCss](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformCss) to use DOMMatrix and require absolute units. #83 + +### d3-quadtree + +* Fix an infinite loop when coordinates diverge to huge values. + +### d3-random + +* Add [d3.randomLcg](https://github.com/d3/d3-random/blob/master/README.md#randomLcg). +* Add [d3.randomGamma](https://github.com/d3/d3-random/blob/master/README.md#randomGamma). +* Add [d3.randomBeta](https://github.com/d3/d3-random/blob/master/README.md#randomBeta). +* Add [d3.randomWeibull](https://github.com/d3/d3-random/blob/master/README.md#randomWeibull). +* Add [d3.randomCauchy](https://github.com/d3/d3-random/blob/master/README.md#randomCauchy). +* Add [d3.randomLogistic](https://github.com/d3/d3-random/blob/master/README.md#randomLogistic). +* Add [d3.randomPoisson](https://github.com/d3/d3-random/blob/master/README.md#randomPoisson). +* Add [d3.randomInt](https://github.com/d3/d3-random/blob/master/README.md#randomInt). +* Add [d3.randomBinomial](https://github.com/d3/d3-random/blob/master/README.md#randomBinomial). +* Add [d3.randomGeometric](https://github.com/d3/d3-random/blob/master/README.md#randomGeometric). +* Add [d3.randomPareto](https://github.com/d3/d3-random/blob/master/README.md#randomPareto). +* Add [d3.randomBernoulli](https://github.com/d3/d3-random/blob/master/README.md#randomBernoulli). +* Allow [d3.randomBates](https://github.com/d3/d3-random/blob/master/README.md#randomBates) to take fractional *n*. +* Allow [d3.randomIrwinHall](https://github.com/d3/d3-random/blob/master/README.md#randomIrwinHall) to take fractional *n*. +* Don’t wrap Math.random in the default source. + +Thanks to @Lange, @p-v-d-Veeken, @svanschooten, @Parcly-Taxel and @jrus for your contributions! + +### d3-scale + +* Accept iterables. +* Add [*diverging*.rangeRound](https://github.com/d3/d3-scale/blob/master/README.md#diverging_rangeRound). +* Add [*sequential*.range](https://github.com/d3/d3-scale/blob/master/README.md#sequential_range) (for compatibility with d3-axis). +* Add [*sequential*.rangeRound](https://github.com/d3/d3-scale/blob/master/README.md#sequential_rangeRound). +* Add [*sequentialQuantile*.quantiles](https://github.com/d3/d3-scale/blob/master/README.md#sequentialQuantile_quantiles). +* Add [d3.scaleRadial](https://github.com/d3/d3-scale/blob/master/README.md#radial-scales). +* [*diverging*.range](https://github.com/d3/d3-scale/blob/master/README.md#diverging_range) can now be used to set the interpolator. +* [*sequential*.range](https://github.com/d3/d3-scale/blob/master/README.md#sequential_range) can now be used to set the interpolator. +* [d3.scaleDiverging](https://github.com/d3/d3-scale/blob/master/README.md#diverging-scales) can now accept a range array in place of an interpolator. +* [d3.scaleSequential](https://github.com/d3/d3-scale/blob/master/README.md#sequential-scales) can now accept a range array in place of an interpolator. +* Fix [*continuous*.nice](https://github.com/d3/d3-scale/blob/master/README.md#continuous_nice) to ensure that niced domains always span ticks. +* Fix [*log*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#log_ticks) for small domains. +* Fix [*log*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#log_ticks) for small domains. #44 +* Fix [*scale*.clamp](https://github.com/d3/d3-scale/blob/master/README.md#continuous_clamp) for [sequential quantile scales](https://github.com/d3/d3-scale/blob/master/README.md#scaleSequentialQuantile). Thanks, @Fil! +* Fix [*scale*.clamp](https://github.com/d3/d3-scale/blob/master/README.md#continuous_clamp) for continuous scales with more domain values than range values. +* Fix [diverging scales](https://github.com/d3/d3-scale/blob/master/README.md#diverging-scales) with descending domains. +* Remove deprecated *step* argument from [*time*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#time_ticks) and [*time*.nice](https://github.com/d3/d3-scale/blob/master/README.md#time_nice). + +### d3-selection + +* Add [*selection*.selectChild](https://github.com/d3/d3-selection/blob/master/README.md#selection_selectChild). +* Add [*selection*.selectChildren](https://github.com/d3/d3-selection/blob/master/README.md#selection_selectChildren). +* Add [d3.pointer](https://github.com/d3/d3-selection/blob/master/README.md#pointer). +* Add [d3.pointers](https://github.com/d3/d3-selection/blob/master/README.md#pointers). +* Add *selection*[Symbol.iterator]; selections are now iterable! +* Accept iterables with [*selection*.data](https://github.com/d3/d3-selection/blob/master/README.md#selection_data). +* Accept iterables with [d3.selectAll](https://github.com/d3/d3-selection/blob/master/README.md#selectAll). +* Change [*selection*.on](https://github.com/d3/d3-selection/blob/master/README.md#selection_on) to pass the *event* directly to listeners. +* Remove index and group from *selection*.on listeners! +* Remove d3.event! +* Remove d3.mouse. +* Remove d3.touch. +* Remove d3.touches. +* Remove d3.customEvent. +* Remove d3.clientPoint. +* Remove d3.sourceEvent. +* Fix *selection*.merge(*transition*) to error. + +For an overview of changes, see https://observablehq.com/@d3/d3-selection-2-0. + +### d3-shape + +* Accept iterables. +* Add [d3.line](https://github.com/d3/d3-shape/blob/master/README.md#line)(*x*, *y*) shorthand. +* Add [d3.area](https://github.com/d3/d3-shape/blob/master/README.md#area)(*x*, *y0*, *y1*) shorthand. +* Add [d3.symbol](https://github.com/d3/d3-shape/blob/master/README.md#symbol)(*type*, *size*) shorthand. + +### d3-time-format + +* Add ISO 8601 “week year” (`%G` and `%g`). + +### d3-timer + +* Fix [*interval*.restart](https://github.com/d3/d3-timer/blob/master/README.md#timer_restart) to restart as an interval. + +### d3-transition + +* Add [*transition*.easeVarying](https://github.com/d3/d3-transition/blob/master/README.md#transition_easeVarying). +* Add *transition*[Symbol.iterator]; transitions are now iterable. +* Fix [*selection*.transition](https://github.com/d3/d3-transition/blob/master/README.md#selection_transition) to error if the named transition to inherit is not found.k +* Fix [*transition*.end](https://github.com/d3/d3-transition/blob/master/README.md#transition_end) to resolve immediately if the selection is empty. + +### d3-zoom + +* Add [*zoom*.tapDistance](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_tapDistance). +* Change [*zoom*.on](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_on) to pass the *event* directly to listeners. +* Change the default [*zoom*.filter](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_filter) to observe *wheel* events if the control key is pressed. +* Change the default [*zoom*.wheelDelta](ttps://github.com/d3/d3-zoom/blob/master/README.md#zoom_wheelDelta) to go faster if the control key is pressed. +* Don‘t set touch-action: none. +* Upgrade to [d3-selection 2](https://observablehq.com/@d3/d3-selection-2-0). + +### Breaking Changes + +D3 6.0 introduces several non-backwards-compatible changes. + +* Remove [d3.event](https://observablehq.com/d/f91cccf0cad5e9cb#events). +* Change [*selection*.on](https://observablehq.com/d/f91cccf0cad5e9cb#events) to pass the *event* directly to listeners. +* Change [*transition*.on](https://observablehq.com/d/f91cccf0cad5e9cb#events) to pass the *event* directly to listeners. +* Change [*brush*.on](https://observablehq.com/d/f91cccf0cad5e9cb#event_brush) to pass the *event* directly to listeners. +* Change [*drag*.on](https://observablehq.com/d/f91cccf0cad5e9cb#event_drag) to pass the *event* directly to listeners. +* Change [*zoom*.on](https://observablehq.com/d/f91cccf0cad5e9cb#event_zoom) to pass the *event* directly to listeners. +* Remove d3.mouse; use [d3.pointer](https://observablehq.com/d/f91cccf0cad5e9cb#pointer). +* Remove d3.touch; use [d3.pointer](https://observablehq.com/d/f91cccf0cad5e9cb#pointer). +* Remove d3.touches; use [d3.pointers](https://observablehq.com/d/f91cccf0cad5e9cb#pointer). +* Remove d3.clientPoint; use [d3.pointer](https://observablehq.com/d/f91cccf0cad5e9cb#pointer). +* Remove d3.voronoi; use [d3.Delaunay](https://observablehq.com/d/f91cccf0cad5e9cb#delaunay). +* Remove d3.nest; use [d3.group](https://observablehq.com/d/f91cccf0cad5e9cb#group) and [d3.rollup](https://observablehq.com/d/f91cccf0cad5e9cb#group). +* Remove d3.map; use [Map](https://observablehq.com/d/f91cccf0cad5e9cb#collection). +* Remove d3.set; use [Set](https://observablehq.com/d/f91cccf0cad5e9cb#collection). +* Remove d3.keys; use [Object.keys](https://observablehq.com/d/f91cccf0cad5e9cb#collection). +* Remove d3.values; use [Object.values](https://observablehq.com/d/f91cccf0cad5e9cb#collection). +* Remove d3.entries; use [Object.entries](https://observablehq.com/d/f91cccf0cad5e9cb#collection). +* Rename d3.histogram to [d3.bin](https://observablehq.com/d/f91cccf0cad5e9cb#bin). +* Rename d3.scan to [d3.leastIndex](https://observablehq.com/d/f91cccf0cad5e9cb#leastIndex). +* Change [d3.interpolateTransformCss](https://observablehq.com/d/f91cccf0cad5e9cb#interpolateTransformCss) to require absolute units. +* Change [d3.format](https://observablehq.com/d/f91cccf0cad5e9cb#minus) to default to the minus sign instead of hyphen-minus for negative values. + +D3 now requires a browser that supports [ES2015](http://www.ecma-international.org/ecma-262/6.0/). For older browsers, you must bring your own transpiler. + +Lastly, support for [Bower](https://bower.io) has been dropped; D3 is now exclusively published to npm and GitHub. + +See our [migration guide](https://observablehq.com/d/f91cccf0cad5e9cb) for help upgrading. + +# Changes in D3 5.0 + +[Released March 22, 2018.](https://github.com/d3/d3/releases/tag/v5.0.0) + +D3 5.0 introduces only a few non-backwards-compatible changes. + +D3 now uses [Promises](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Using_promises) instead of asynchronous callbacks to load data. Promises simplify the structure of asynchronous code, especially in modern browsers that support [async and await](https://javascript.info/async-await). (See this [introduction to promises](https://observablehq.com/@observablehq/introduction-to-promises) on [Observable](https://observablehq.com).) For example, to load a CSV file in v4, you might say: + +```js +d3.csv("file.csv", function(error, data) { + if (error) throw error; + console.log(data); +}); +``` + +In v5, using promises: + +```js +d3.csv("file.csv").then(function(data) { + console.log(data); +}); +``` + +Note that you don’t need to rethrow the error—the promise will reject automatically, and you can *promise*.catch if desired. Using await, the code is even simpler: + +```js +const data = await d3.csv("file.csv"); +console.log(data); +``` + +With the adoption of promises, D3 now uses the [Fetch API](https://fetch.spec.whatwg.org/) instead of [XMLHttpRequest](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest): the [d3-request](https://github.com/d3/d3-request) module has been replaced by [d3-fetch](https://github.com/d3/d3-fetch). Fetch supports many powerful new features, such as [streaming responses](https://observablehq.com/@mbostock/streaming-shapefiles). D3 5.0 also deprecates and removes the [d3-queue](https://github.com/d3/d3-queue) module. Use [Promise.all](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) to run a batch of asynchronous tasks in parallel, or a helper library such as [p-queue](https://github.com/sindresorhus/p-queue) to [control concurrency](https://observablehq.com/@mbostock/hello-p-queue). + +D3 no longer provides the d3.schemeCategory20* categorical color schemes. These twenty-color schemes were flawed because their grouped design could falsely imply relationships in the data: a shared hue can imply that the encoded data are part of a group (a super-category), while relative lightness can imply order. Instead, D3 now includes [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic), which implements excellent schemes from ColorBrewer, including [categorical](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#categorical), [diverging](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#diverging), [sequential single-hue](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#sequential-single-hue) and [sequential multi-hue](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#sequential-multi-hue) schemes. These schemes are available in both discrete and continuous variants. + +D3 now provides implementations of [marching squares](https://observablehq.com/@d3/contours) and [density estimation](https://observablehq.com/@d3/density-contours) via [d3-contour](https://github.com/d3/d3-contour)! There are two new [d3-selection](https://github.com/d3/d3-selection) methods: [*selection*.clone](https://github.com/d3/d3-selection/blob/master/README.md#selection_clone) for inserting clones of the selected nodes, and [d3.create](https://github.com/d3/d3-selection/blob/master/README.md#create) for creating detached elements. [Geographic projections](https://github.com/d3/d3-geo) now support [*projection*.angle](https://github.com/d3/d3-geo/blob/master/README.md#projection_angle), which has enabled several fantastic new [polyhedral projections](https://github.com/d3/d3-geo-polygon) by Philippe Rivière. + +Lastly, D3’s [package.json](https://github.com/d3/d3/blob/master/package.json) no longer pins exact versions of the dependent D3 modules. This fixes an issue with [duplicate installs](https://github.com/d3/d3/issues/3256) of D3 modules. + +# Changes in D3 4.0 + +[Released June 28, 2016.](https://github.com/d3/d3/releases/tag/v4.0.0) + +D3 4.0 is modular. Instead of one library, D3 is now [many small libraries](#table-of-contents) that are designed to work together. You can pick and choose which parts to use as you see fit. Each library is maintained in its own repository, allowing decentralized ownership and independent release cycles. The default bundle combines about thirty of these microlibraries. + +```html + +``` + +As before, you can load optional plugins on top of the default bundle, such as [ColorBrewer scales](https://github.com/d3/d3-scale-chromatic): + +```html + + +``` + +You are not required to use the default bundle! If you’re just using [d3-selection](https://github.com/d3/d3-selection), use it as a standalone library. Like the default bundle, you can load D3 microlibraries using vanilla script tags or RequireJS (great for HTTP/2!): + +```html + +``` + +You can also `cat` D3 microlibraries into a custom bundle, or use tools such as [Webpack](https://webpack.github.io/) and [Rollup](http://rollupjs.org/) to create [optimized bundles](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4). Custom bundles are great for applications that use a subset of D3’s features; for example, a React chart library might use D3 for scales and shapes, and React to manipulate the DOM. The D3 microlibraries are written as [ES6 modules](http://www.2ality.com/2014/09/es6-modules-final.html), and Rollup lets you pick at the symbol level to produce smaller bundles. + +Small files are nice, but modularity is also about making D3 more *fun*. Microlibraries are easier to understand, develop and test. They make it easier for new people to get involved and contribute. They reduce the distinction between a “core module” and a “plugin”, and increase the pace of development in D3 features. + +If you don’t care about modularity, you can mostly ignore this change and keep using the default bundle. However, there is one unavoidable consequence of adopting ES6 modules: every symbol in D3 4.0 now shares a flat namespace rather than the nested one of D3 3.x. For example, d3.scale.linear is now d3.scaleLinear, and d3.layout.treemap is now d3.treemap. The adoption of ES6 modules also means that D3 is now written exclusively in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) and has better readability. And there have been many other significant improvements to D3’s features! (Nearly all of the code from D3 3.x has been rewritten.) These changes are covered below. + +### Other Global Changes + +The default [UMD bundle](https://github.com/umdjs/umd) is now [anonymous](https://github.com/requirejs/requirejs/wiki/Updating-existing-libraries#register-as-an-anonymous-module-). No `d3` global is exported if AMD or CommonJS is detected. In a vanilla environment, the D3 microlibraries share the `d3` global, even if you load them independently; thus, code you write is the same whether or not you use the default bundle. (See [Let’s Make a (D3) Plugin](https://bost.ocks.org/mike/d3-plugin/) for more.) The generated bundle is no longer stored in the Git repository; Bower has been repointed to [d3-bower](https://github.com/mbostock-bower/d3-bower), and you can find the generated files on [npm](https://unpkg.com/d3) or attached to the [latest release](https://github.com/d3/d3/releases/latest). The non-minified default bundle is no longer mangled, making it more readable and preserving inline comments. + +To the consternation of some users, 3.x employed Unicode variable names such as λ, φ, τ and π for a concise representation of mathematical operations. A downside of this approach was that a SyntaxError would occur if you loaded the non-minified D3 using ISO-8859-1 instead of UTF-8. 3.x also used Unicode string literals, such as the SI-prefix µ for 1e-6. 4.0 uses only ASCII variable names and ASCII string literals (see [rollup-plugin-ascii](https://github.com/mbostock/rollup-plugin-ascii)), avoiding encoding problems. + +### Table of Contents + +* [Arrays](#arrays-d3-array) +* [Axes](#axes-d3-axis) +* [Brushes](#brushes-d3-brush) +* [Chords](#chords-d3-chord) +* [Collections](#collections-d3-collection) +* [Colors](#colors-d3-color) +* [Dispatches](#dispatches-d3-dispatch) +* [Dragging](#dragging-d3-drag) +* [Delimiter-Separated Values](#delimiter-separated-values-d3-dsv) +* [Easings](#easings-d3-ease) +* [Forces](#forces-d3-force) +* [Number Formats](#number-formats-d3-format) +* [Geographies](#geographies-d3-geo) +* [Hierarchies](#hierarchies-d3-hierarchy) +* [Internals](#internals) +* [Interpolators](#interpolators-d3-interpolate) +* [Paths](#paths-d3-path) +* [Polygons](#polygons-d3-polygon) +* [Quadtrees](#quadtrees-d3-quadtree) +* [Queues](#queues-d3-queue) +* [Random Numbers](#random-numbers-d3-random) +* [Requests](#requests-d3-request) +* [Scales](#scales-d3-scale) +* [Selections](#selections-d3-selection) +* [Shapes](#shapes-d3-shape) +* [Time Formats](#time-formats-d3-time-format) +* [Time Intervals](#time-intervals-d3-time) +* [Timers](#timers-d3-timer) +* [Transitions](#transitions-d3-transition) +* [Voronoi Diagrams](#voronoi-diagrams-d3-voronoi) +* [Zooming](#zooming-d3-zoom) + +## [Arrays (d3-array)](https://github.com/d3/d3-array/blob/master/README.md) + +The new [d3.scan](https://github.com/d3/d3-array/blob/master/README.md#scan) method performs a linear scan of an array, returning the index of the least element according to the specified comparator. This is similar to [d3.min](https://github.com/d3/d3-array/blob/master/README.md#min) and [d3.max](https://github.com/d3/d3-array/blob/master/README.md#max), except you can use it to find the position of an extreme element, rather than just calculate an extreme value. + +```js +var data = [ + {name: "Alice", value: 2}, + {name: "Bob", value: 3}, + {name: "Carol", value: 1}, + {name: "Dwayne", value: 5} +]; + +var i = d3.scan(data, function(a, b) { return a.value - b.value; }); // 2 +data[i]; // {name: "Carol", value: 1} +``` + +The new [d3.ticks](https://github.com/d3/d3-array/blob/master/README.md#ticks) and [d3.tickStep](https://github.com/d3/d3-array/blob/master/README.md#tickStep) methods are useful for generating human-readable numeric ticks. These methods are a low-level alternative to [*continuous*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#continuous_ticks) from [d3-scale](https://github.com/d3/d3-scale). The new implementation is also more accurate, returning the optimal number of ticks as measured by relative error. + +```js +var ticks = d3.ticks(0, 10, 5); // [0, 2, 4, 6, 8, 10] +``` + +The [d3.range](https://github.com/d3/d3-array/blob/master/README.md#range) method no longer makes an elaborate attempt to avoid floating-point error when *step* is not an integer. The returned values are strictly defined as *start* + *i* \* *step*, where *i* is an integer. (Learn more about [floating point math](http://0.30000000000000004.com/).) d3.range returns the empty array for infinite ranges, rather than throwing an error. + +The method signature for optional accessors has been changed to be more consistent with array methods such as [*array*.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach): the accessor is passed the current element (*d*), the index (*i*), and the array (*data*), with *this* as undefined. This affects [d3.min](https://github.com/d3/d3-array/blob/master/README.md#min), [d3.max](https://github.com/d3/d3-array/blob/master/README.md#max), [d3.extent](https://github.com/d3/d3-array/blob/master/README.md#extent), [d3.sum](https://github.com/d3/d3-array/blob/master/README.md#sum), [d3.mean](https://github.com/d3/d3-array/blob/master/README.md#mean), [d3.median](https://github.com/d3/d3-array/blob/master/README.md#median), [d3.quantile](https://github.com/d3/d3-array/blob/master/README.md#quantile), [d3.variance](https://github.com/d3/d3-array/blob/master/README.md#variance) and [d3.deviation](https://github.com/d3/d3-array/blob/master/README.md#deviation). The [d3.quantile](https://github.com/d3/d3-array/blob/master/README.md#quantile) method previously did not take an accessor. Some methods with optional arguments now treat those arguments as missing if they are null or undefined, rather than strictly checking arguments.length. + +The new [d3.histogram](https://github.com/d3/d3-array/blob/master/README.md#histograms) API replaces d3.layout.histogram. Rather than exposing *bin*.x and *bin*.dx on each returned bin, the histogram exposes *bin*.x0 and *bin*.x1, guaranteeing that *bin*.x0 is exactly equal to *bin*.x1 on the preceding bin. The “frequency” and “probability” modes are no longer supported; each bin is simply an array of elements from the input data, so *bin*.length is equal to D3 3.x’s *bin*.y in frequency mode. To compute a probability distribution, divide the number of elements in each bin by the total number of elements. + +The *histogram*.range method has been renamed [*histogram*.domain](https://github.com/d3/d3-array/blob/master/README.md#histogram_domain) for consistency with scales. The *histogram*.bins method has been renamed [*histogram*.thresholds](https://github.com/d3/d3-array/blob/master/README.md#histogram_thresholds), and no longer accepts an upper value: *n* thresholds will produce *n* + 1 bins. If you specify a desired number of bins rather than thresholds, d3.histogram now uses [d3.ticks](https://github.com/d3/d3-array/blob/master/README.md#ticks) to compute nice bin thresholds. In addition to the default Sturges’ formula, D3 now implements the [Freedman-Diaconis rule](https://github.com/d3/d3-array/blob/master/README.md#thresholdFreedmanDiaconis) and [Scott’s normal reference rule](https://github.com/d3/d3-array/blob/master/README.md#thresholdScott). + +## [Axes (d3-axis)](https://github.com/d3/d3-axis/blob/master/README.md) + +To render axes properly in D3 3.x, you needed to style them: + +```html + + +``` + +If you didn’t, you saw this: + + + +D3 4.0 provides default styles and shorter syntax. In place of d3.svg.axis and *axis*.orient, D3 4.0 now provides four constructors for each orientation: [d3.axisTop](https://github.com/d3/d3-axis/blob/master/README.md#axisTop), [d3.axisRight](https://github.com/d3/d3-axis/blob/master/README.md#axisRight), [d3.axisBottom](https://github.com/d3/d3-axis/blob/master/README.md#axisBottom), [d3.axisLeft](https://github.com/d3/d3-axis/blob/master/README.md#axisLeft). These constructors accept a scale, so you can reduce all of the above to: + +```html + +``` + +And get this: + + + +As before, you can customize the axis appearance either by applying stylesheets or by modifying the axis elements. The default appearance has been changed slightly to offset the axis by a half-pixel; this fixes a crisp-edges rendering issue on Safari where the axis would be drawn two-pixels thick. + +There’s now an [*axis*.tickArguments](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickArguments) method, as an alternative to [*axis*.ticks](https://github.com/d3/d3-axis/blob/master/README.md#axis_ticks) that also allows the axis tick arguments to be inspected. The [*axis*.tickSize](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSize) method has been changed to only allow a single argument when setting the tick size. The *axis*.innerTickSize and *axis*.outerTickSize methods have been renamed [*axis*.tickSizeInner](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSizeInner) and [*axis*.tickSizeOuter](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSizeOuter), respectively. + +## [Brushes (d3-brush)](https://github.com/d3/d3-brush/blob/master/README.md) + +Replacing d3.svg.brush, there are now three classes of brush for brushing along the *x*-dimension, the *y*-dimension, or both: [d3.brushX](https://github.com/d3/d3-brush/blob/master/README.md#brushX), [d3.brushY](https://github.com/d3/d3-brush/blob/master/README.md#brushY), [d3.brush](https://github.com/d3/d3-brush/blob/master/README.md#brush). Brushes are no longer dependent on [scales](#scales-d3-scale); instead, each brush defines a selection in screen coordinates. This selection can be [inverted](https://github.com/d3/d3-scale/blob/master/README.md#continuous_invert) if you want to compute the corresponding data domain. And rather than rely on the scales’ ranges to determine the brushable area, there is now a [*brush*.extent](https://github.com/d3/d3-brush/blob/master/README.md#brush_extent) method for setting it. If you do not set the brush extent, it defaults to the full extent of the owner SVG element. The *brush*.clamp method has also been eliminated; brushing is always restricted to the brushable area defined by the brush extent. + +Brushes no longer store the active brush selection (*i.e.*, the highlighted region; the brush’s position) internally. The brush’s position is now stored on any elements to which the brush has been applied. The brush’s position is available as *event*.selection within a brush event or by calling [d3.brushSelection](https://github.com/d3/d3-brush/blob/master/README.md#brushSelection) on a given *element*. To move the brush programmatically, use [*brush*.move](https://github.com/d3/d3-brush/blob/master/README.md#brush_move) with a given [selection](#selections-d3-selection) or [transition](#transitions-d3-transition); see the [brush snapping example](https://bl.ocks.org/mbostock/6232537). The *brush*.event method has been removed. + +Brush interaction has been improved. By default, brushes now ignore right-clicks intended for the context menu; you can change this behavior using [*brush*.filter](https://github.com/d3/d3-brush/blob/master/README.md#brush_filter). Brushes also ignore emulated mouse events on iOS. Holding down SHIFT (⇧) while brushing locks the *x*- or *y*-position of the brush. Holding down META (⌘) while clicking and dragging starts a new selection, rather than translating the existing selection. + +The default appearance of the brush has also been improved and slightly simplified. Previously it was necessary to apply styles to the brush to give it a reasonable appearance, such as: + +```css +.brush .extent { + stroke: #fff; + fill-opacity: .125; + shape-rendering: crispEdges; +} +``` + +These styles are now applied by default as attributes; if you want to customize the brush appearance, you can still apply external styles or modify the brush elements. (D3 4.0 features a similar improvement to [axes](#axes-d3-axis).) A new [*brush*.handleSize](https://github.com/d3/d3-brush/blob/master/README.md#brush_handleSize) method lets you override the brush handle size; it defaults to six pixels. + +The brush now consumes handled events, making it easier to combine with other interactive behaviors such as [dragging](#dragging-d3-drag) and [zooming](#zooming-d3-zoom). The *brushstart* and *brushend* events have been renamed to *start* and *end*, respectively. The brush event no longer reports a *event*.mode to distinguish between resizing and dragging the brush. + +## [Chords (d3-chord)](https://github.com/d3/d3-chord/blob/master/README.md) + +Pursuant to the great namespace flattening: + +* d3.layout.chord ↦ [d3.chord](https://github.com/d3/d3-chord/blob/master/README.md#chord) +* d3.svg.chord ↦ [d3.ribbon](https://github.com/d3/d3-chord/blob/master/README.md#ribbon) + +For consistency with [*arc*.padAngle](https://github.com/d3/d3-shape/blob/master/README.md#arc_padAngle), *chord*.padding has also been renamed to [*ribbon*.padAngle](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_padAngle). A new [*ribbon*.context](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_context) method lets you render chord diagrams to Canvas! See also [d3-path](#paths-d3-path). + +## [Collections (d3-collection)](https://github.com/d3/d3-collection/blob/master/README.md) + +The [d3.set](https://github.com/d3/d3-collection/blob/master/README.md#set) constructor now accepts an existing set for making a copy. If you pass an array to d3.set, you can also pass a value accessor. This accessor takes the standard arguments: the current element (*d*), the index (*i*), and the array (*data*), with *this* undefined. For example: + +```js +var yields = [ + {yield: 22.13333, variety: "Manchuria", year: 1932, site: "Grand Rapids"}, + {yield: 26.76667, variety: "Peatland", year: 1932, site: "Grand Rapids"}, + {yield: 28.10000, variety: "No. 462", year: 1931, site: "Duluth"}, + {yield: 38.50000, variety: "Svansota", year: 1932, site: "Waseca"}, + {yield: 40.46667, variety: "Svansota", year: 1931, site: "Crookston"}, + {yield: 36.03333, variety: "Peatland", year: 1932, site: "Waseca"}, + {yield: 34.46667, variety: "Wisconsin No. 38", year: 1931, site: "Grand Rapids"} +]; + +var sites = d3.set(yields, function(d) { return d.site; }); // Grand Rapids, Duluth, Waseca, Crookston +``` + +The [d3.map](https://github.com/d3/d3-collection/blob/master/README.md#map) constructor also follows the standard array accessor argument pattern. + +The *map*.forEach and *set*.forEach methods have been renamed to [*map*.each](https://github.com/d3/d3-collection/blob/master/README.md#map_each) and [*set*.each](https://github.com/d3/d3-collection/blob/master/README.md#set_each) respectively. The order of arguments for *map*.each has also been changed to *value*, *key* and *map*, while the order of arguments for *set*.each is now *value*, *value* and *set*. This is closer to ES6 [*map*.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach) and [*set*.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach). Also like ES6 Map and Set, *map*.set and *set*.add now return the current collection (rather than the added value) to facilitate method chaining. New [*map*.clear](https://github.com/d3/d3-collection/blob/master/README.md#map_clear) and [*set*.clear](https://github.com/d3/d3-collection/blob/master/README.md#set_clear) methods can be used to empty collections. + +The [*nest*.map](https://github.com/d3/d3-collection/blob/master/README.md#nest_map) method now always returns a d3.map instance. For a plain object, use [*nest*.object](https://github.com/d3/d3-collection/blob/master/README.md#nest_object) instead. When used in conjunction with [*nest*.rollup](https://github.com/d3/d3-collection/blob/master/README.md#nest_rollup), [*nest*.entries](https://github.com/d3/d3-collection/blob/master/README.md#nest_entries) now returns {key, value} objects for the leaf entries, instead of {key, values}. This makes *nest*.rollup easier to use in conjunction with [hierarchies](#hierarchies-d3-hierarchy), as in this [Nest Treemap example](https://bl.ocks.org/mbostock/2838bf53e0e65f369f476afd653663a2). + +## [Colors (d3-color)](https://github.com/d3/d3-color/blob/master/README.md) + +All colors now have opacity exposed as *color*.opacity, which is a number in [0, 1]. You can pass an optional opacity argument to the color space constructors [d3.rgb](https://github.com/d3/d3-color/blob/master/README.md#rgb), [d3.hsl](https://github.com/d3/d3-color/blob/master/README.md#hsl), [d3.lab](https://github.com/d3/d3-color/blob/master/README.md#lab), [d3.hcl](https://github.com/d3/d3-color/blob/master/README.md#hcl) or [d3.cubehelix](https://github.com/d3/d3-color/blob/master/README.md#cubehelix). + +You can now parse rgba(…) and hsla(…) CSS color specifiers or the string “transparent” using [d3.color](https://github.com/d3/d3-color/blob/master/README.md#color). The “transparent” color is defined as an RGB color with zero opacity and undefined red, green and blue channels; this differs slightly from CSS which defines it as transparent black, but is useful for simplifying color interpolation logic where either the starting or ending color has undefined channels. The [*color*.toString](https://github.com/d3/d3-color/blob/master/README.md#color_toString) method now likewise returns an rgb(…) or rgba(…) string with integer channel values, not the hexadecimal RGB format, consistent with CSS computed values. This improves performance by short-circuiting transitions when the element’s starting style matches its ending style. + +The new [d3.color](https://github.com/d3/d3-color/blob/master/README.md#color) method is the primary method for parsing colors: it returns a d3.color instance in the appropriate color space, or null if the CSS color specifier is invalid. For example: + +```js +var red = d3.color("hsl(0, 80%, 50%)"); // {h: 0, l: 0.5, s: 0.8, opacity: 1} +``` + +The parsing implementation is now more robust. For example, you can no longer mix integers and percentages in rgb(…), and it correctly handles whitespace, decimal points, number signs, and other edge cases. The color space constructors d3.rgb, d3.hsl, d3.lab, d3.hcl and d3.cubehelix now always return a copy of the input color, converted to the corresponding color space. While [*color*.rgb](https://github.com/d3/d3-color/blob/master/README.md#color_rgb) remains, *rgb*.hsl has been removed; use d3.hsl to convert a color to the RGB color space. + +The RGB color space no longer greedily quantizes and clamps channel values when creating colors, improving accuracy in color space conversion. Quantization and clamping now occurs in *color*.toString when formatting a color for display. You can use the new [*color*.displayable](https://github.com/d3/d3-color/blob/master/README.md#color_displayable) to test whether a color is [out-of-gamut](https://en.wikipedia.org/wiki/Gamut). + +The [*rgb*.brighter](https://github.com/d3/d3-color/blob/master/README.md#rgb_brighter) method no longer special-cases black. This is a multiplicative operator, defining a new color *r*′, *g*′, *b*′ where *r*′ = *r* × *pow*(0.7, *k*), *g*′ = *g* × *pow*(0.7, *k*) and *b*′ = *b* × *pow*(0.7, *k*); a brighter black is still black. + +There’s a new [d3.cubehelix](https://github.com/d3/d3-color/blob/master/README.md#cubehelix) color space, generalizing Dave Green’s color scheme! (See also [d3.interpolateCubehelixDefault](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCubehelixDefault) from [d3-scale](#scales-d3-scale).) You can continue to define your own custom color spaces, too; see [d3-hsv](https://github.com/d3/d3-hsv) for an example. + +## [Dispatches (d3-dispatch)](https://github.com/d3/d3-dispatch/blob/master/README.md) + +Rather than decorating the *dispatch* object with each event type, the dispatch object now exposes generic [*dispatch*.call](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_call) and [*dispatch*.apply](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_apply) methods which take the *type* string as the first argument. For example, in D3 3.x, you might say: + +```js +dispatcher.foo.call(that, "Hello, Foo!"); +``` + +To dispatch a *foo* event in D3 4.0, you’d say: + +```js +dispatcher.call("foo", that, "Hello, Foo!"); +``` + +The [*dispatch*.on](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_on) method now accepts multiple typenames, allowing you to add or remove listeners for multiple events simultaneously. For example, to send both *foo* and *bar* events to the same listener: + +```js +dispatcher.on("foo bar", function(message) { + console.log(message); +}); +``` + +This matches the new behavior of [*selection*.on](https://github.com/d3/d3-selection/blob/master/README.md#selection_on) in [d3-selection](#selections-d3-selection). The *dispatch*.on method now validates that the specifier *listener* is a function, rather than throwing an error in the future. + +The new implementation d3.dispatch is faster, using fewer closures to improve performance. There’s also a new [*dispatch*.copy](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_copy) method for making a copy of a dispatcher; this is used by [d3-transition](#transitions-d3-transition) to improve the performance of transitions in the common case where all elements in a transition have the same transition event listeners. + +## [Dragging (d3-drag)](https://github.com/d3/d3-drag/blob/master/README.md) + +The drag behavior d3.behavior.drag has been renamed to d3.drag. The *drag*.origin method has been replaced by [*drag*.subject](https://github.com/d3/d3-drag/blob/master/README.md#drag_subject), which allows you to define the thing being dragged at the start of a drag gesture. This is particularly useful with Canvas, where draggable objects typically share a Canvas element (as opposed to SVG, where draggable objects typically have distinct DOM elements); see the [circle dragging example](https://bl.ocks.org/mbostock/444757cc9f0fde320a5f469cd36860f4). + +A new [*drag*.container](https://github.com/d3/d3-drag/blob/master/README.md#drag_container) method lets you override the parent element that defines the drag gesture coordinate system. This defaults to the parent node of the element to which the drag behavior was applied. For dragging on Canvas elements, you probably want to use the Canvas element as the container. + +[Drag events](https://github.com/d3/d3-drag/blob/master/README.md#drag-events) now expose an [*event*.on](https://github.com/d3/d3-drag/blob/master/README.md#event_on) method for registering temporary listeners for duration of the current drag gesture; these listeners can capture state for the current gesture, such as the thing being dragged. A new *event*.active property lets you detect whether multiple (multitouch) drag gestures are active concurrently. The *dragstart* and *dragend* events have been renamed to *start* and *end*. By default, drag behaviors now ignore right-clicks intended for the context menu; use [*drag*.filter](https://github.com/d3/d3-drag/blob/master/README.md#drag_filter) to control which events are ignored. The drag behavior also ignores emulated mouse events on iOS. The drag behavior now consumes handled events, making it easier to combine with other interactive behaviors such as [zooming](#zooming-d3-zoom). + +The new [d3.dragEnable](https://github.com/d3/d3-drag/blob/master/README.md#dragEnable) and [d3.dragDisable](https://github.com/d3/d3-drag/blob/master/README.md#dragDisable) methods provide a low-level API for implementing drag gestures across browsers and devices. These methods are also used by other D3 components, such as the [brush](#brushes-d3-brush). + +## [Delimiter-Separated Values (d3-dsv)](https://github.com/d3/d3-dsv/blob/master/README.md) + +Pursuant to the great namespace flattening, various CSV and TSV methods have new names: + +* d3.csv.parse ↦ [d3.csvParse](https://github.com/d3/d3-dsv/blob/master/README.md#csvParse) +* d3.csv.parseRows ↦ [d3.csvParseRows](https://github.com/d3/d3-dsv/blob/master/README.md#csvParseRows) +* d3.csv.format ↦ [d3.csvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#csvFormat) +* d3.csv.formatRows ↦ [d3.csvFormatRows](https://github.com/d3/d3-dsv/blob/master/README.md#csvFormatRows) +* d3.tsv.parse ↦ [d3.tsvParse](https://github.com/d3/d3-dsv/blob/master/README.md#tsvParse) +* d3.tsv.parseRows ↦ [d3.tsvParseRows](https://github.com/d3/d3-dsv/blob/master/README.md#tsvParseRows) +* d3.tsv.format ↦ [d3.tsvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#tsvFormat) +* d3.tsv.formatRows ↦ [d3.tsvFormatRows](https://github.com/d3/d3-dsv/blob/master/README.md#tsvFormatRows) + +The [d3.csv](https://github.com/d3/d3-request/blob/master/README.md#csv) and [d3.tsv](https://github.com/d3/d3-request/blob/master/README.md#tsv) methods for loading files of the corresponding formats have not been renamed, however! Those are defined in [d3-request](#requests-d3-request).There’s no longer a d3.dsv method, which served the triple purpose of defining a DSV formatter, a DSV parser and a DSV requestor; instead, there’s just [d3.dsvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#dsvFormat) which you can use to define a DSV formatter and parser. You can use [*request*.response](https://github.com/d3/d3-request/blob/master/README.md#request_response) to make a request and then parse the response body, or just use [d3.text](https://github.com/d3/d3-request/blob/master/README.md#text). + +The [*dsv*.parse](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_parse) method now exposes the column names and their input order as *data*.columns. For example: + +```js +d3.csv("cars.csv", function(error, data) { + if (error) throw error; + console.log(data.columns); // ["Year", "Make", "Model", "Length"] +}); +``` + +You can likewise pass an optional array of column names to [*dsv*.format](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_format) to format only a subset of columns, or to specify the column order explicitly: + +```js +var string = d3.csvFormat(data, ["Year", "Model", "Length"]); +``` + +The parser is a bit faster and the formatter is a bit more robust: inputs are coerced to strings before formatting, fixing an obscure crash, and deprecated support for falling back to [*dsv*.formatRows](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_formatRows) when the input *data* is an array of arrays has been removed. + +## [Easings (d3-ease)](https://github.com/d3/d3-ease/blob/master/README.md) + +D3 3.x used strings, such as “cubic-in-out”, to identify easing methods; these strings could be passed to d3.ease or *transition*.ease. D3 4.0 uses symbols instead, such as [d3.easeCubicInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicInOut). Symbols are simpler and cleaner. They work well with Rollup to produce smaller custom bundles. You can still define your own custom easing function, too, if desired. Here’s the full list of equivalents: + +* linear ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹ +* linear-in ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹ +* linear-out ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹ +* linear-in-out ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹ +* linear-out-in ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹ +* poly-in ↦ [d3.easePolyIn](https://github.com/d3/d3-ease/blob/master/README.md#easePolyIn) +* poly-out ↦ [d3.easePolyOut](https://github.com/d3/d3-ease/blob/master/README.md#easePolyOut) +* poly-in-out ↦ [d3.easePolyInOut](https://github.com/d3/d3-ease/blob/master/README.md#easePolyInOut) +* poly-out-in ↦ REMOVED² +* quad-in ↦ [d3.easeQuadIn](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadIn) +* quad-out ↦ [d3.easeQuadOut](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadOut) +* quad-in-out ↦ [d3.easeQuadInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadInOut) +* quad-out-in ↦ REMOVED² +* cubic-in ↦ [d3.easeCubicIn](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicIn) +* cubic-out ↦ [d3.easeCubicOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicOut) +* cubic-in-out ↦ [d3.easeCubicInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicInOut) +* cubic-out-in ↦ REMOVED² +* sin-in ↦ [d3.easeSinIn](https://github.com/d3/d3-ease/blob/master/README.md#easeSinIn) +* sin-out ↦ [d3.easeSinOut](https://github.com/d3/d3-ease/blob/master/README.md#easeSinOut) +* sin-in-out ↦ [d3.easeSinInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeSinInOut) +* sin-out-in ↦ REMOVED² +* exp-in ↦ [d3.easeExpIn](https://github.com/d3/d3-ease/blob/master/README.md#easeExpIn) +* exp-out ↦ [d3.easeExpOut](https://github.com/d3/d3-ease/blob/master/README.md#easeExpOut) +* exp-in-out ↦ [d3.easeExpInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeExpInOut) +* exp-out-in ↦ REMOVED² +* circle-in ↦ [d3.easeCircleIn](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleIn) +* circle-out ↦ [d3.easeCircleOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleOut) +* circle-in-out ↦ [d3.easeCircleInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleInOut) +* circle-out-in ↦ REMOVED² +* elastic-in ↦ [d3.easeElasticOut](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticOut)² +* elastic-out ↦ [d3.easeElasticIn](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticIn)² +* elastic-in-out ↦ REMOVED² +* elastic-out-in ↦ [d3.easeElasticInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticInOut)² +* back-in ↦ [d3.easeBackIn](https://github.com/d3/d3-ease/blob/master/README.md#easeBackIn) +* back-out ↦ [d3.easeBackOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBackOut) +* back-in-out ↦ [d3.easeBackInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBackInOut) +* back-out-in ↦ REMOVED² +* bounce-in ↦ [d3.easeBounceOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceOut)² +* bounce-out ↦ [d3.easeBounceIn](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceIn)² +* bounce-in-out ↦ REMOVED² +* bounce-out-in ↦ [d3.easeBounceInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceInOut)² + +¹ The -in, -out and -in-out variants of linear easing are identical, so there’s just d3.easeLinear. +
² Elastic and bounce easing were inadvertently reversed in 3.x, so 4.0 eliminates -out-in easing! + +For convenience, there are also default aliases for each easing method. For example, [d3.easeCubic](https://github.com/d3/d3-ease/blob/master/README.md#easeCubic) is an alias for [d3.easeCubicInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicInOut). Most default to -in-out; the exceptions are [d3.easeBounce](https://github.com/d3/d3-ease/blob/master/README.md#easeBounce) and [d3.easeElastic](https://github.com/d3/d3-ease/blob/master/README.md#easeElastic), which default to -out. + +Rather than pass optional arguments to d3.ease or *transition*.ease, parameterizable easing functions now have named parameters: [*poly*.exponent](https://github.com/d3/d3-ease/blob/master/README.md#poly_exponent), [*elastic*.amplitude](https://github.com/d3/d3-ease/blob/master/README.md#elastic_amplitude), [*elastic*.period](https://github.com/d3/d3-ease/blob/master/README.md#elastic_period) and [*back*.overshoot](https://github.com/d3/d3-ease/blob/master/README.md#back_overshoot). For example, in D3 3.x you might say: + +```js +var e = d3.ease("elastic-out-in", 1.2); +``` + +The equivalent in D3 4.0 is: + +```js +var e = d3.easeElastic.amplitude(1.2); +``` + +Many of the easing functions have been optimized for performance and accuracy. Several bugs have been fixed, as well, such as the interpretation of the overshoot parameter for back easing, and the period parameter for elastic easing. Also, [d3-transition](#transitions-d3-transition) now explicitly guarantees that the last tick of the transition happens at exactly *t* = 1, avoiding floating point errors in some easing functions. + +There’s now a nice [visual reference](https://github.com/d3/d3-ease/blob/master/README.md) and an [animated reference](https://bl.ocks.org/mbostock/248bac3b8e354a9103c4) to the new easing functions, too! + +## [Forces (d3-force)](https://github.com/d3/d3-force/blob/master/README.md) + +The force layout d3.layout.force has been renamed to d3.forceSimulation. The force simulation now uses [velocity Verlet integration](https://en.wikipedia.org/wiki/Verlet_integration#Velocity_Verlet) rather than position Verlet, tracking the nodes’ positions (*node*.x, *node*.y) and velocities (*node*.vx, *node*.vy) rather than their previous positions (*node*.px, *node*.py). + +Rather than hard-coding a set of built-in forces, the force simulation is now extensible: you specify which forces you want! The approach affords greater flexibility through composition. The new forces are more flexible, too: force parameters can typically be configured per-node or per-link. There are separate positioning forces for [*x*](https://github.com/d3/d3-force/blob/master/README.md#forceX) and [*y*](https://github.com/d3/d3-force/blob/master/README.md#forceY) that replace *force*.gravity; [*x*.x](https://github.com/d3/d3-force/blob/master/README.md#x_x) and [*y*.y](https://github.com/d3/d3-force/blob/master/README.md#y_y) replace *force*.size. The new [link force](https://github.com/d3/d3-force/blob/master/README.md#forceLink) replaces *force*.linkStrength and employs better default heuristics to improve stability. The new [many-body force](https://github.com/d3/d3-force/blob/master/README.md#forceManyBody) replaces *force*.charge and supports a new [minimum-distance parameter](https://github.com/d3/d3-force/blob/master/README.md#manyBody_distanceMin) and performance improvements thanks to 4.0’s [new quadtrees](#quadtrees-d3-quadtree). There are also brand-new forces for [centering nodes](https://github.com/d3/d3-force/blob/master/README.md#forceCenter) and [collision resolution](https://github.com/d3/d3-force/blob/master/README.md#forceCollision). + +The new forces and simulation have been carefully crafted to avoid nondeterminism. Rather than initializing nodes randomly, if the nodes do not have preset positions, they are placed in a phyllotaxis pattern: + +Phyllotaxis + +Random jitter is still needed to resolve link, collision and many-body forces if there are coincident nodes, but at least in the common case, the force simulation (and the resulting force-directed graph layout) is now consistent across browsers and reloads. D3 no longer plays dice! + +The force simulation has several new methods for greater control over heating, such as [*simulation*.alphaMin](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaMin) and [*simulation*.alphaDecay](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaDecay), and the internal timer. Calling [*simulation*.alpha](https://github.com/d3/d3-force/blob/master/README.md#simulation_alpha) now has no effect on the internal timer, which is controlled independently via [*simulation*.stop](https://github.com/d3/d3-force/blob/master/README.md#simulation_stop) and [*simulation*.restart](https://github.com/d3/d3-force/blob/master/README.md#simulation_restart). The force layout’s internal timer now starts automatically on creation, removing *force*.start. As in 3.x, you can advance the simulation manually using [*simulation*.tick](https://github.com/d3/d3-force/blob/master/README.md#simulation_tick). The *force*.friction parameter is replaced by *simulation*.velocityDecay. A new [*simulation*.alphaTarget](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaTarget) method allows you to set the desired alpha (temperature) of the simulation, such that the simulation can be smoothly reheated during interaction, and then smoothly cooled again. This improves the stability of the graph during interaction. + +The force layout no longer depends on the [drag behavior](#dragging-d3-drag), though you can certainly create [draggable force-directed graphs](https://bl.ocks.org/mbostock/ad70335eeef6d167bc36fd3c04378048)! Set *node*.fx and *node*.fy to fix a node’s position. As an alternative to a [Voronoi](#voronoi-d3-voronoi) SVG overlay, you can now use [*simulation*.find](https://github.com/d3/d3-force/blob/master/README.md#simulation_find) to find the closest node to a pointer. + +## [Number Formats (d3-format)](https://github.com/d3/d3-format/blob/master/README.md) + +If a precision is not specified, the formatting behavior has changed: there is now a default precision of 6 for all directives except *none*, which defaults to 12. In 3.x, if you did not specify a precision, the number was formatted using its shortest unique representation (per [*number*.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString)); this could lead to unexpected digits due to [floating point math](http://0.30000000000000004.com/). The new default precision in 4.0 produces more consistent results: + +```js +var f = d3.format("e"); +f(42); // "4.200000e+1" +f(0.1 + 0.2); // "3.000000e-1" +``` + +To trim insignificant trailing zeroes, use the *none* directive, which is similar `g`. For example: + +```js +var f = d3.format(".3"); +f(0.12345); // "0.123" +f(0.10000); // "0.1" +f(0.1 + 0.2); // "0.3" +``` + +Under the hood, number formatting has improved accuracy with very large and very small numbers by using [*number*.toExponential](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) rather than [Math.log](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log) to extract the mantissa and exponent. Negative zero (-0, an IEEE 754 construct) and very small numbers that round to zero are now formatted as unsigned zero. The inherently unsafe d3.round method has been removed, along with d3.requote. + +The [d3.formatPrefix](https://github.com/d3/d3-format/blob/master/README.md#formatPrefix) method has been changed. Rather than returning an SI-prefix string, it returns an SI-prefix format function for a given *specifier* and reference *value*. For example, to format thousands: + +```js +var f = d3.formatPrefix(",.0", 1e3); +f(1e3); // "1k" +f(1e4); // "10k" +f(1e5); // "100k" +f(1e6); // "1,000k" +``` + +Unlike the `s` format directive, d3.formatPrefix always employs the same SI-prefix, producing consistent results: + +```js +var f = d3.format(".0s"); +f(1e3); // "1k" +f(1e4); // "10k" +f(1e5); // "100k" +f(1e6); // "1M" +``` + +The new `(` sign option uses parentheses for negative values. This is particularly useful in conjunction with `$`. For example: + +```js +d3.format("+.0f")(-42); // "-42" +d3.format("(.0f")(-42); // "(42)" +d3.format("+$.0f")(-42); // "-$42" +d3.format("($.0f")(-42); // "($42)" +``` + +The new `=` align option places any sign and symbol to the left of any padding: + +```js +d3.format(">6d")(-42); // " -42" +d3.format("=6d")(-42); // "- 42" +d3.format(">(6d")(-42); // " (42)" +d3.format("=(6d")(-42); // "( 42)" +``` + +The `b`, `o`, `d` and `x` directives now round to the nearest integer, rather than returning the empty string for non-integers: + +```js +d3.format("b")(41.9); // "101010" +d3.format("o")(41.9); // "52" +d3.format("d")(41.9); // "42" +d3.format("x")(41.9); // "2a" +``` + +The `c` directive is now for character data (*i.e.*, literal strings), not for character codes. The is useful if you just want to apply padding and alignment and don’t care about formatting numbers. For example, the infamous [left-pad](http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm) (as well as center- and right-pad!) can be conveniently implemented as: + +```js +d3.format(">10c")("foo"); // " foo" +d3.format("^10c")("foo"); // " foo " +d3.format("<10c")("foo"); // "foo " +``` + +There are several new methods for computing suggested decimal precisions; these are used by [d3-scale](#scales-d3-scale) for tick formatting, and are helpful for implementing custom number formats: [d3.precisionFixed](https://github.com/d3/d3-format/blob/master/README.md#precisionFixed), [d3.precisionPrefix](https://github.com/d3/d3-format/blob/master/README.md#precisionPrefix) and [d3.precisionRound](https://github.com/d3/d3-format/blob/master/README.md#precisionRound). There’s also a new [d3.formatSpecifier](https://github.com/d3/d3-format/blob/master/README.md#formatSpecifier) method for parsing, validating and debugging format specifiers; it’s also good for deriving related format specifiers, such as when you want to substitute the precision automatically. + +You can now set the default locale using [d3.formatDefaultLocale](https://github.com/d3/d3-format/blob/master/README.md#formatDefaultLocale)! The locales are published as [JSON](https://github.com/d3/d3-request/blob/master/README.md#json) to [npm](https://unpkg.com/d3-format/locale/). + +## [Geographies (d3-geo)](https://github.com/d3/d3-geo/blob/master/README.md) + +Pursuant to the great namespace flattening, various methods have new names: + +* d3.geo.graticule ↦ [d3.geoGraticule](https://github.com/d3/d3-geo/blob/master/README.md#geoGraticule) +* d3.geo.circle ↦ [d3.geoCircle](https://github.com/d3/d3-geo/blob/master/README.md#geoCircle) +* d3.geo.area ↦ [d3.geoArea](https://github.com/d3/d3-geo/blob/master/README.md#geoArea) +* d3.geo.bounds ↦ [d3.geoBounds](https://github.com/d3/d3-geo/blob/master/README.md#geoBounds) +* d3.geo.centroid ↦ [d3.geoCentroid](https://github.com/d3/d3-geo/blob/master/README.md#geoCentroid) +* d3.geo.distance ↦ [d3.geoDistance](https://github.com/d3/d3-geo/blob/master/README.md#geoDistance) +* d3.geo.interpolate ↦ [d3.geoInterpolate](https://github.com/d3/d3-geo/blob/master/README.md#geoInterpolate) +* d3.geo.length ↦ [d3.geoLength](https://github.com/d3/d3-geo/blob/master/README.md#geoLength) +* d3.geo.rotation ↦ [d3.geoRotation](https://github.com/d3/d3-geo/blob/master/README.md#geoRotation) +* d3.geo.stream ↦ [d3.geoStream](https://github.com/d3/d3-geo/blob/master/README.md#geoStream) +* d3.geo.path ↦ [d3.geoPath](https://github.com/d3/d3-geo/blob/master/README.md#geoPath) +* d3.geo.projection ↦ [d3.geoProjection](https://github.com/d3/d3-geo/blob/master/README.md#geoProjection) +* d3.geo.projectionMutator ↦ [d3.geoProjectionMutator](https://github.com/d3/d3-geo/blob/master/README.md#geoProjectionMutator) +* d3.geo.albers ↦ [d3.geoAlbers](https://github.com/d3/d3-geo/blob/master/README.md#geoAlbers) +* d3.geo.albersUsa ↦ [d3.geoAlbersUsa](https://github.com/d3/d3-geo/blob/master/README.md#geoAlbersUsa) +* d3.geo.azimuthalEqualArea ↦ [d3.geoAzimuthalEqualArea](https://github.com/d3/d3-geo/blob/master/README.md#geoAzimuthalEqualArea) +* d3.geo.azimuthalEquidistant ↦ [d3.geoAzimuthalEquidistant](https://github.com/d3/d3-geo/blob/master/README.md#geoAzimuthalEquidistant) +* d3.geo.conicConformal ↦ [d3.geoConicConformal](https://github.com/d3/d3-geo/blob/master/README.md#geoConicConformal) +* d3.geo.conicEqualArea ↦ [d3.geoConicEqualArea](https://github.com/d3/d3-geo/blob/master/README.md#geoConicEqualArea) +* d3.geo.conicEquidistant ↦ [d3.geoConicEquidistant](https://github.com/d3/d3-geo/blob/master/README.md#geoConicEquidistant) +* d3.geo.equirectangular ↦ [d3.geoEquirectangular](https://github.com/d3/d3-geo/blob/master/README.md#geoEquirectangular) +* d3.geo.gnomonic ↦ [d3.geoGnomonic](https://github.com/d3/d3-geo/blob/master/README.md#geoGnomonic) +* d3.geo.mercator ↦ [d3.geoMercator](https://github.com/d3/d3-geo/blob/master/README.md#geoMercator) +* d3.geo.orthographic ↦ [d3.geoOrthographic](https://github.com/d3/d3-geo/blob/master/README.md#geoOrthographic) +* d3.geo.stereographic ↦ [d3.geoStereographic](https://github.com/d3/d3-geo/blob/master/README.md#geoStereographic) +* d3.geo.transverseMercator ↦ [d3.geoTransverseMercator](https://github.com/d3/d3-geo/blob/master/README.md#geoTransverseMercator) + +Also renamed for consistency: + +* *circle*.origin ↦ [*circle*.center](https://github.com/d3/d3-geo/blob/master/README.md#circle_center) +* *circle*.angle ↦ [*circle*.radius](https://github.com/d3/d3-geo/blob/master/README.md#circle_radius) +* *graticule*.majorExtent ↦ [*graticule*.extentMajor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_extentMajor) +* *graticule*.minorExtent ↦ [*graticule*.extentMinor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_extentMinor) +* *graticule*.majorStep ↦ [*graticule*.stepMajor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_stepMajor) +* *graticule*.minorStep ↦ [*graticule*.stepMinor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_stepMinor) + +Projections now have more appropriate defaults. For example, [d3.geoOrthographic](https://github.com/d3/d3-geo/blob/master/README.md#geoOrthographic) has a 90° clip angle by default, showing only the front hemisphere, and [d3.geoGnomonic](https://github.com/d3/d3-geo/blob/master/README.md#geoGnomonic) has a default 60° clip angle. The default [projection](https://github.com/d3/d3-geo/blob/master/README.md#path_projection) for [d3.geoPath](https://github.com/d3/d3-geo/blob/master/README.md#geoPath) is now null rather than [d3.geoAlbersUsa](https://github.com/d3/d3-geo/blob/master/README.md#geoAlbersUsa); a null projection is used with [pre-projected geometry](https://bl.ocks.org/mbostock/5557726) and is typically faster to render. + +“Fallback projections”—when you pass a function rather than a projection to [*path*.projection](https://github.com/d3/d3-geo/blob/master/README.md#path_projection)—are no longer supported. For geographic projections, use [d3.geoProjection](https://github.com/d3/d3-geo/blob/master/README.md#geoProjection) or [d3.geoProjectionMutator](https://github.com/d3/d3-geo/blob/master/README.md#geoProjectionMutator) to define a custom projection. For arbitrary geometry transformations, implement the [stream interface](https://github.com/d3/d3-geo/blob/master/README.md#streams); see also [d3.geoTransform](https://github.com/d3/d3-geo/blob/master/README.md#geoTransform). The “raw” projections (e.g., d3.geo.equirectangular.raw) are no longer exported. + +## [Hierarchies (d3-hierarchy)](https://github.com/d3/d3-hierarchy/blob/master/README.md) + +Pursuant to the great namespace flattening: + +* d3.layout.cluster ↦ [d3.cluster](https://github.com/d3/d3-hierarchy/blob/master/README.md#cluster) +* d3.layout.hierarchy ↦ [d3.hierarchy](https://github.com/d3/d3-hierarchy/blob/master/README.md#hierarchy) +* d3.layout.pack ↦ [d3.pack](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack) +* d3.layout.partition ↦ [d3.partition](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition) +* d3.layout.tree ↦ [d3.tree](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree) +* d3.layout.treemap ↦ [d3.treemap](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap) + +As an alternative to using JSON to represent hierarchical data (such as the “flare.json format” used by many D3 examples), the new [d3.stratify](https://github.com/d3/d3-hierarchy/blob/master/README.md#stratify) operator simplifies the conversion of tabular data to hierarchical data! This is convenient if you already have data in a tabular format, such as the result of a SQL query or a CSV file: + +``` +name,parent +Eve, +Cain,Eve +Seth,Eve +Enos,Seth +Noam,Seth +Abel,Eve +Awan,Eve +Enoch,Awan +Azura,Eve +``` + +To convert this to a root [*node*](https://github.com/d3/d3-hierarchy/blob/master/README.md#hierarchy): + +```js +var root = d3.stratify() + .id(function(d) { return d.name; }) + .parentId(function(d) { return d.parent; }) + (nodes); +``` + +The resulting *root* can be passed to [d3.tree](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree) to produce a tree diagram like this: + + + +Root nodes can also be created from JSON data using [d3.hierarchy](https://github.com/d3/d3-hierarchy/blob/master/README.md#hierarchy). The hierarchy layouts now take these root nodes as input rather than operating directly on JSON data, which helps to provide a cleaner separation between the input data and the computed layout. (For example, use [*node*.copy](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_copy) to isolate layout changes.) It also simplifies the API: rather than each hierarchy layout needing to implement value and sorting accessors, there are now generic [*node*.sum](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_sum) and [*node*.sort](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_sort) methods that work with any hierarchy layout. + +The new d3.hierarchy API also provides a richer set of methods for manipulating hierarchical data. For example, to generate an array of all nodes in topological order, use [*node*.descendants](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_descendants); for just leaf nodes, use [*node*.leaves](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_leaves). To highlight the ancestors of a given *node* on mouseover, use [*node*.ancestors](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_ancestors). To generate an array of {source, target} links for a given hierarchy, use [*node*.links](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_links); this replaces *treemap*.links and similar methods on the other layouts. The new [*node*.path](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_path) method replaces d3.layout.bundle; see also [d3.curveBundle](https://github.com/d3/d3-shape/blob/master/README.md#curveBundle) for hierarchical edge bundling. + +The hierarchy layouts have been rewritten using new, non-recursive traversal methods ([*node*.each](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_each), [*node*.eachAfter](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_eachAfter) and [*node*.eachBefore](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_eachBefore)), improving performance on large datasets. The d3.tree layout no longer uses a *node*.\_ field to store temporary state during layout. + +Treemap tiling is now [extensible](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap-tiling) via [*treemap*.tile](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_tile)! The default squarified tiling algorithm, [d3.treemapSquarify](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapSquarify), has been completely rewritten, improving performance and fixing bugs in padding and rounding. The *treemap*.sticky method has been replaced with the [d3.treemapResquarify](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapResquarify), which is identical to d3.treemapSquarify except it performs stable neighbor-preserving updates. The *treemap*.ratio method has been replaced with [*squarify*.ratio](https://github.com/d3/d3-hierarchy/blob/master/README.md#squarify_ratio). And there’s a new [d3.treemapBinary](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapBinary) for binary treemaps! + +Treemap padding has also been improved. The treemap now distinguishes between [outer padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingOuter) that separates a parent from its children, and [inner padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingInner) that separates adjacent siblings. You can set the [top-](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingTop), [right-](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingRight), [bottom-](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingBottom) and [left-](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingLeft)outer padding separately. There are new examples for the traditional [nested treemap](https://bl.ocks.org/mbostock/911ad09bdead40ec0061) and for Lü and Fogarty’s [cascaded treemap](https://bl.ocks.org/mbostock/f85ffb3a5ac518598043). And there’s a new example demonstrating [d3.nest with d3.treemap](https://bl.ocks.org/mbostock/2838bf53e0e65f369f476afd653663a2). + +The space-filling layouts [d3.treemap](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap) and [d3.partition](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition) now output *x0*, *x1*, *y0*, *y1* on each node instead of *x0*, *dx*, *y0*, *dy*. This improves accuracy by ensuring that the edges of adjacent cells are exactly equal, rather than sometimes being slightly off due to floating point math. The partition layout now supports [rounding](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition_round) and [padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition_padding). + +The circle-packing layout, [d3.pack](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack), has been completely rewritten to better implement Wang et al.’s algorithm, fixing major bugs and improving results! Welzl’s algorithm is now used to compute the exact [smallest enclosing circle](https://bl.ocks.org/mbostock/29c534ff0b270054a01c) for each parent, rather than the approximate answer used by Wang et al. The 3.x output is shown on the left; 4.0 is shown on the right: + +Circle Packing in 3.x Circle Packing in 4.0 + +A non-hierarchical implementation is also available as [d3.packSiblings](https://github.com/d3/d3-hierarchy/blob/master/README.md#packSiblings), and the smallest enclosing circle implementation is available as [d3.packEnclose](https://github.com/d3/d3-hierarchy/blob/master/README.md#packEnclose). [Pack padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack_padding) now applies between a parent and its children, as well as between adjacent siblings. In addition, you can now specify padding as a function that is computed dynamically for each parent. + +## Internals + +The d3.rebind method has been removed. (See the [3.x source](https://github.com/d3/d3/blob/v3.5.17/src/core/rebind.js).) If you want to wrap a getter-setter method, the recommend pattern is to implement a wrapper method and check the return value. For example, given a *component* that uses an internal [*dispatch*](#dispatches-d3-dispatch), *component*.on can rebind *dispatch*.on as follows: + +```js +component.on = function() { + var value = dispatch.on.apply(dispatch, arguments); + return value === dispatch ? component : value; +}; +``` + +The d3.functor method has been removed. (See the [3.x source](https://github.com/d3/d3/blob/v3.5.17/src/core/functor.js).) If you want to promote a constant value to a function, the recommended pattern is to implement a closure that returns the constant value. If desired, you can use a helper method as follows: + +```js +function constant(x) { + return function() { + return x; + }; +} +``` + +Given a value *x*, to promote *x* to a function if it is not already: + +```js +var fx = typeof x === "function" ? x : constant(x); +``` + +## [Interpolators (d3-interpolate)](https://github.com/d3/d3-interpolate/blob/master/README.md) + +The [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) method no longer delegates to d3.interpolators, which has been removed; its behavior is now defined by the library. It is now slightly faster in the common case that *b* is a number. It only uses [d3.interpolateRgb](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgb) if *b* is a valid CSS color specifier (and not approximately one). And if the end value *b* is null, undefined, true or false, d3.interpolate now returns a constant function which always returns *b*. + +The behavior of [d3.interpolateObject](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateObject) and [d3.interpolateArray](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateArray) has changed slightly with respect to properties or elements in the start value *a* that do not exist in the end value *b*: these properties and elements are now ignored, such that the ending value of the interpolator at *t* = 1 is now precisely equal to *b*. So, in 3.x: + +```js +d3.interpolateObject({foo: 2, bar: 1}, {foo: 3})(0.5); // {bar: 1, foo: 2.5} in 3.x +``` + +Whereas in 4.0, *a*.bar is ignored: + +```js +d3.interpolateObject({foo: 2, bar: 1}, {foo: 3})(0.5); // {foo: 2.5} in 4.0 +``` + +If *a* or *b* are undefined or not an object, they are now implicitly converted to the empty object or empty array as appropriate, rather than throwing a TypeError. + +The d3.interpolateTransform interpolator has been renamed to [d3.interpolateTransformSvg](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformSvg), and there is a new [d3.interpolateTransformCss](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformCss) to interpolate CSS transforms! This allows [d3-transition](#transitions-d3-transition) to automatically interpolate both the SVG [transform attribute](https://www.w3.org/TR/SVG/coords.html#TransformAttribute) and the CSS [transform style property](https://www.w3.org/TR/css-transforms-1/#transform-property). (Note, however, that only 2D CSS transforms are supported.) The d3.transform method has been removed. + +Color space interpolators now interpolate opacity (see [d3-color](#colors-d3-color)) and return rgb(…) or rgba(…) CSS color specifier strings rather than using the RGB hexadecimal format. This is necessary to support opacity interpolation, but is also beneficial because it matches CSS computed values. When a channel in the start color *a* is undefined, color interpolators now use the corresponding channel value from the end color *b*, or *vice versa*. This logic previously applied to some channels (such as saturation in HSL), but now applies to all channels in all color spaces, and is especially useful when interpolating to or from transparent. + +There are now “long” versions of cylindrical color space interpolators: [d3.interpolateHslLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHslLong), [d3.interpolateHclLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHclLong) and [d3.interpolateCubehelixLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelixLong). These interpolators use linear interpolation of hue, rather than using the shortest path around the 360° hue circle. See [d3.interpolateRainbow](https://github.com/d3/d3-scale/blob/master/README.md#interpolateRainbow) for an example. The Cubehelix color space is now supported by [d3-color](#colors-d3-color), and so there are now [d3.interpolateCubehelix](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelix) and [d3.interpolateCubehelixLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelixLong) interpolators. + +[Gamma-corrected color interpolation](https://web.archive.org/web/20160112115812/http://www.4p8.com/eric.brasseur/gamma.html) is now supported for both RGB and Cubehelix color spaces as [*interpolate*.gamma](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate_gamma). For example, to interpolate from purple to orange with a gamma of 2.2 in RGB space: + +```js +var interpolate = d3.interpolateRgb.gamma(2.2)("purple", "orange"); +``` + +There are new interpolators for uniform non-rational [B-splines](https://en.wikipedia.org/wiki/B-spline)! These are useful for smoothly interpolating between an arbitrary sequence of values from *t* = 0 to *t* = 1, such as to generate a smooth color gradient from a discrete set of colors. The [d3.interpolateBasis](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateBasis) and [d3.interpolateBasisClosed](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateBasisClosed) interpolators generate one-dimensional B-splines, while [d3.interpolateRgbBasis](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgbBasis) and [d3.interpolateRgbBasisClosed](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgbBasisClosed) generate three-dimensional B-splines through RGB color space. These are used by [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) to generate continuous color scales from ColorBrewer’s discrete color schemes, such as [PiYG](https://bl.ocks.org/mbostock/048d21cf747371b11884f75ad896e5a5). + +There’s also now a [d3.quantize](https://github.com/d3/d3-interpolate/blob/master/README.md#quantize) method for generating uniformly-spaced discrete samples from a continuous interpolator. This is useful for taking one of the built-in color scales (such as [d3.interpolateViridis](https://github.com/d3/d3-scale/blob/master/README.md#interpolateViridis)) and quantizing it for use with [d3.scaleQuantize](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantize), [d3.scaleQuantile](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantile) or [d3.scaleThreshold](https://github.com/d3/d3-scale/blob/master/README.md#scaleThreshold). + +## [Paths (d3-path)](https://github.com/d3/d3-path/blob/master/README.md) + +The [d3.path](https://github.com/d3/d3-path/blob/master/README.md#path) serializer implements the [CanvasPathMethods API](https://www.w3.org/TR/2dcontext/#canvaspathmethods), allowing you to write code that can render to either Canvas or SVG. For example, given some code that draws to a canvas: + +```js +function drawCircle(context, radius) { + context.moveTo(radius, 0); + context.arc(0, 0, radius, 0, 2 * Math.PI); +} +``` + +You can render to SVG as follows: + +```js +var context = d3.path(); +drawCircle(context, 40); +pathElement.setAttribute("d", context.toString()); +``` + +The path serializer enables [d3-shape](#shapes-d3-shape) to support both Canvas and SVG; see [*line*.context](https://github.com/d3/d3-shape/blob/master/README.md#line_context) and [*area*.context](https://github.com/d3/d3-shape/blob/master/README.md#area_context), for example. + +## [Polygons (d3-polygon)](https://github.com/d3/d3-polygon/blob/master/README.md) + +There’s no longer a d3.geom.polygon constructor; instead you just pass an array of vertices to the polygon methods. So instead of *polygon*.area and *polygon*.centroid, there’s [d3.polygonArea](https://github.com/d3/d3-polygon/blob/master/README.md#polygonArea) and [d3.polygonCentroid](https://github.com/d3/d3-polygon/blob/master/README.md#polygonCentroid). There are also new [d3.polygonContains](https://github.com/d3/d3-polygon/blob/master/README.md#polygonContains) and [d3.polygonLength](https://github.com/d3/d3-polygon/blob/master/README.md#polygonLength) methods. There’s no longer an equivalent to *polygon*.clip, but if [Sutherland–Hodgman clipping](https://en.wikipedia.org/wiki/Sutherland–Hodgman_algorithm) is needed, please [file a feature request](https://github.com/d3/d3-polygon/issues). + +The d3.geom.hull operator has been simplified: instead of an operator with *hull*.x and *hull*.y accessors, there’s just the [d3.polygonHull](https://github.com/d3/d3-polygon/blob/master/README.md#polygonHull) method which takes an array of points and returns the convex hull. + +## [Quadtrees (d3-quadtree)](https://github.com/d3/d3-quadtree/blob/master/README.md) + +The d3.geom.quadtree method has been replaced by [d3.quadtree](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree). 4.0 removes the concept of quadtree “generators” (configurable functions that build a quadtree from an array of data); there are now just quadtrees, which you can create via d3.quadtree and add data to via [*quadtree*.add](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_add) and [*quadtree*.addAll](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_addAll). This code in 3.x: + +```js +var quadtree = d3.geom.quadtree() + .extent([[0, 0], [width, height]]) + (data); +``` + +Can be rewritten in 4.0 as: + +```js +var quadtree = d3.quadtree() + .extent([[0, 0], [width, height]]) + .addAll(data); +``` + +The new quadtree implementation is vastly improved! It is no longer recursive, avoiding stack overflows when there are large numbers of coincident points. The internal storage is now more efficient, and the implementation is also faster; constructing a quadtree of 1M normally-distributed points takes about one second in 4.0, as compared to three seconds in 3.x. + +The change in [internal *node* structure](https://github.com/d3/d3-quadtree/blob/master/README.md#nodes) affects [*quadtree*.visit](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_visit): use *node*.length to distinguish leaf nodes from internal nodes. For example, to iterate over all data in a quadtree: + +```js +quadtree.visit(function(node) { + if (!node.length) { + do { + console.log(node.data); + } while (node = node.next) + } +}); +``` + +There’s a new [*quadtree*.visitAfter](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_visitAfter) method for visiting nodes in post-order traversal. This feature is used in [d3-force](#forces-d3-force) to implement the [Barnes–Hut approximation](https://en.wikipedia.org/wiki/Barnes–Hut_simulation). + +You can now remove data from a quadtree using [*quadtree*.remove](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_remove) and [*quadtree*.removeAll](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_removeAll). When adding data to a quadtree, the quadtree will now expand its extent by repeated doubling if the new point is outside the existing extent of the quadtree. There are also [*quadtree*.extent](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_extent) and [*quadtree*.cover](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_cover) methods for explicitly expanding the extent of the quadtree after creation. + +Quadtrees support several new utility methods: [*quadtree*.copy](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_copy) returns a copy of the quadtree sharing the same data; [*quadtree*.data](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_data) generates an array of all data in the quadtree; [*quadtree*.size](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_size) returns the number of data points in the quadtree; and [*quadtree*.root](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_root) returns the root node, which is useful for manual traversal of the quadtree. The [*quadtree*.find](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_find) method now takes an optional search radius, which is useful for pointer-based selection in [force-directed graphs](https://bl.ocks.org/mbostock/ad70335eeef6d167bc36fd3c04378048). + +## [Queues (d3-queue)](https://github.com/d3/d3-queue/blob/master/README.md) + +Formerly known as Queue.js and queue-async, [d3.queue](https://github.com/d3/d3-queue) is now included in the default bundle, making it easy to load data files in parallel. It has been rewritten with fewer closures to improve performance, and there are now stricter checks in place to guarantee well-defined behavior. You can now use instanceof d3.queue and inspect the queue’s internal private state. + +## [Random Numbers (d3-random)](https://github.com/d3/d3-random/blob/master/README.md) + +Pursuant to the great namespace flattening, the random number generators have new names: + +* d3.random.normal ↦ [d3.randomNormal](https://github.com/d3/d3-random/blob/master/README.md#randomNormal) +* d3.random.logNormal ↦ [d3.randomLogNormal](https://github.com/d3/d3-random/blob/master/README.md#randomLogNormal) +* d3.random.bates ↦ [d3.randomBates](https://github.com/d3/d3-random/blob/master/README.md#randomBates) +* d3.random.irwinHall ↦ [d3.randomIrwinHall](https://github.com/d3/d3-random/blob/master/README.md#randomIrwinHall) + +There are also new random number generators for [exponential](https://github.com/d3/d3-random/blob/master/README.md#randomExponential) and [uniform](https://github.com/d3/d3-random/blob/master/README.md#randomUniform) distributions. The [normal](https://github.com/d3/d3-random/blob/master/README.md#randomNormal) and [log-normal](https://github.com/d3/d3-random/blob/master/README.md#randomLogNormal) random generators have been optimized. + +## [Requests (d3-request)](https://github.com/d3/d3-request/blob/master/README.md) + +The d3.xhr method has been renamed to [d3.request](https://github.com/d3/d3-request/blob/master/README.md#request). Basic authentication is now supported using [*request*.user](https://github.com/d3/d3-request/blob/master/README.md#request_user) and [*request*.password](https://github.com/d3/d3-request/blob/master/README.md#request_password). You can now configure a timeout using [*request*.timeout](https://github.com/d3/d3-request/blob/master/README.md#request_timeout). + +If an error occurs, the corresponding [ProgressEvent](https://xhr.spec.whatwg.org/#interface-progressevent) of type “error” is now passed to the error listener, rather than the [XMLHttpRequest](https://xhr.spec.whatwg.org/#interface-xmlhttprequest). Likewise, the ProgressEvent is passed to progress event listeners, rather than using [d3.event](https://github.com/d3/d3-selection/blob/master/README.md#event). If [d3.xml](https://github.com/d3/d3-request/blob/master/README.md#xml) encounters an error parsing XML, this error is now reported to error listeners rather than returning a null response. + +The [d3.request](https://github.com/d3/d3-request/blob/master/README.md#request), [d3.text](https://github.com/d3/d3-request/blob/master/README.md#text) and [d3.xml](https://github.com/d3/d3-request/blob/master/README.md#xml) methods no longer take an optional mime type as the second argument; use [*request*.mimeType](https://github.com/d3/d3-request/blob/master/README.md#request_mimeType) instead. For example: + +```js +d3.xml("file.svg").mimeType("image/svg+xml").get(function(error, svg) { + … +}); +``` + +With the exception of [d3.html](https://github.com/d3/d3-request/blob/master/README.md#html) and [d3.xml](https://github.com/d3/d3-request/blob/master/README.md#xml), Node is now supported via [node-XMLHttpRequest](https://github.com/driverdan/node-XMLHttpRequest). + +## [Scales (d3-scale)](https://github.com/d3/d3-scale/blob/master/README.md) + +Pursuant to the great namespace flattening: + +* d3.scale.linear ↦ [d3.scaleLinear](https://github.com/d3/d3-scale/blob/master/README.md#scaleLinear) +* d3.scale.sqrt ↦ [d3.scaleSqrt](https://github.com/d3/d3-scale/blob/master/README.md#scaleSqrt) +* d3.scale.pow ↦ [d3.scalePow](https://github.com/d3/d3-scale/blob/master/README.md#scalePow) +* d3.scale.log ↦ [d3.scaleLog](https://github.com/d3/d3-scale/blob/master/README.md#scaleLog) +* d3.scale.quantize ↦ [d3.scaleQuantize](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantize) +* d3.scale.threshold ↦ [d3.scaleThreshold](https://github.com/d3/d3-scale/blob/master/README.md#scaleThreshold) +* d3.scale.quantile ↦ [d3.scaleQuantile](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantile) +* d3.scale.identity ↦ [d3.scaleIdentity](https://github.com/d3/d3-scale/blob/master/README.md#scaleIdentity) +* d3.scale.ordinal ↦ [d3.scaleOrdinal](https://github.com/d3/d3-scale/blob/master/README.md#scaleOrdinal) +* d3.time.scale ↦ [d3.scaleTime](https://github.com/d3/d3-scale/blob/master/README.md#scaleTime) +* d3.time.scale.utc ↦ [d3.scaleUtc](https://github.com/d3/d3-scale/blob/master/README.md#scaleUtc) + +Scales now generate ticks in the same order as the domain: if you have a descending domain, you now get descending ticks. This change affects the order of tick elements generated by [axes](#axes-d3-axis). For example: + +```js +d3.scaleLinear().domain([10, 0]).ticks(5); // [10, 8, 6, 4, 2, 0] +``` + +[Log tick formatting](https://github.com/d3/d3-scale/blob/master/README.md#log_tickFormat) now assumes a default *count* of ten, not Infinity, if not specified. Log scales with domains that span many powers (such as from 1e+3 to 1e+29) now return only one [tick](https://github.com/d3/d3-scale/blob/master/README.md#log_ticks) per power rather than returning *base* ticks per power. Non-linear quantitative scales are slightly more accurate. + +You can now control whether an ordinal scale’s domain is implicitly extended when the scale is passed a value that is not already in its domain. By default, [*ordinal*.unknown](https://github.com/d3/d3-scale/blob/master/README.md#ordinal_unknown) is [d3.scaleImplicit](https://github.com/d3/d3-scale/blob/master/README.md#scaleImplicit), causing unknown values to be added to the domain: + +```js +var x = d3.scaleOrdinal() + .domain([0, 1]) + .range(["red", "green", "blue"]); + +x.domain(); // [0, 1] +x(2); // "blue" +x.domain(); // [0, 1, 2] +``` + +By setting *ordinal*.unknown, you instead define the output value for unknown inputs. This is particularly useful for choropleth maps where you want to assign a color to missing data. + +```js +var x = d3.scaleOrdinal() + .domain([0, 1]) + .range(["red", "green", "blue"]) + .unknown(undefined); + +x.domain(); // [0, 1] +x(2); // undefined +x.domain(); // [0, 1] +``` + +The *ordinal*.rangeBands and *ordinal*.rangeRoundBands methods have been replaced with a new subclass of ordinal scale: [band scales](https://github.com/d3/d3-scale/blob/master/README.md#band-scales). The following code in 3.x: + +```js +var x = d3.scale.ordinal() + .domain(["a", "b", "c"]) + .rangeBands([0, width]); +``` + +Is equivalent to this in 4.0: + +```js +var x = d3.scaleBand() + .domain(["a", "b", "c"]) + .range([0, width]); +``` + +The new [*band*.padding](https://github.com/d3/d3-scale/blob/master/README.md#band_padding), [*band*.paddingInner](https://github.com/d3/d3-scale/blob/master/README.md#band_paddingInner) and [*band*.paddingOuter](https://github.com/d3/d3-scale/blob/master/README.md#band_paddingOuter) methods replace the optional arguments to *ordinal*.rangeBands. The new [*band*.bandwidth](https://github.com/d3/d3-scale/blob/master/README.md#band_bandwidth) and [*band*.step](https://github.com/d3/d3-scale/blob/master/README.md#band_step) methods replace *ordinal*.rangeBand. There’s also a new [*band*.align](https://github.com/d3/d3-scale/blob/master/README.md#band_align) method which you can use to control how the extra space outside the bands is distributed, say to shift columns closer to the *y*-axis. + +Similarly, the *ordinal*.rangePoints and *ordinal*.rangeRoundPoints methods have been replaced with a new subclass of ordinal scale: [point scales](https://github.com/d3/d3-scale/blob/master/README.md#point-scales). The following code in 3.x: + +```js +var x = d3.scale.ordinal() + .domain(["a", "b", "c"]) + .rangePoints([0, width]); +``` + +Is equivalent to this in 4.0: + +```js +var x = d3.scalePoint() + .domain(["a", "b", "c"]) + .range([0, width]); +``` + +The new [*point*.padding](https://github.com/d3/d3-scale/blob/master/README.md#point_padding) method replaces the optional *padding* argument to *ordinal*.rangePoints. Like *ordinal*.rangeBand with *ordinal*.rangePoints, the [*point*.bandwidth](https://github.com/d3/d3-scale/blob/master/README.md#point_bandwidth) method always returns zero; a new [*point*.step](https://github.com/d3/d3-scale/blob/master/README.md#point_step) method returns the interval between adjacent points. + +The [ordinal scale constructor](https://github.com/d3/d3-scale/blob/master/README.md#ordinal-scales) now takes an optional *range* for a shorter alternative to [*ordinal*.range](https://github.com/d3/d3-scale/blob/master/README.md#ordinal_range). This is especially useful now that the categorical color scales have been changed to simple arrays of colors rather than specialized ordinal scale constructors: + +* d3.scale.category10 ↦ [d3.schemeCategory10](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory10) +* d3.scale.category20 ↦ [d3.schemeCategory20](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20) +* d3.scale.category20b ↦ [d3.schemeCategory20b](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20b) +* d3.scale.category20c ↦ [d3.schemeCategory20c](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20c) + +The following code in 3.x: + +```js +var color = d3.scale.category10(); +``` + +Is equivalent to this in 4.0: + +```js +var color = d3.scaleOrdinal(d3.schemeCategory10); +``` + +[Sequential scales](https://github.com/d3/d3-scale/blob/master/README.md#scaleSequential), are a new class of scales with a fixed output [interpolator](https://github.com/d3/d3-scale/blob/master/README.md#sequential_interpolator) instead of a [range](https://github.com/d3/d3-scale/blob/master/README.md#continuous_range). Typically these scales are used to implement continuous sequential or diverging color schemes. Inspired by Matplotlib’s new [perceptually-motived colormaps](https://bids.github.io/colormap/), 4.0 now features [viridis](https://github.com/d3/d3-scale/blob/master/README.md#interpolateViridis), [inferno](https://github.com/d3/d3-scale/blob/master/README.md#interpolateInferno), [magma](https://github.com/d3/d3-scale/blob/master/README.md#interpolateMagma), [plasma](https://github.com/d3/d3-scale/blob/master/README.md#interpolatePlasma) interpolators for use with sequential scales. Using [d3.quantize](https://github.com/d3/d3-interpolate/blob/master/README.md#quantize), these interpolators can also be applied to [quantile](https://github.com/d3/d3-scale/blob/master/README.md#quantile-scales), [quantize](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales) and [threshold](https://github.com/d3/d3-scale/blob/master/README.md#threshold-scales) scales. + +[viridis](https://github.com/d3/d3-scale/blob/master/README.md#interpolateViridis) +[inferno](https://github.com/d3/d3-scale/blob/master/README.md#interpolateInferno) +[magma](https://github.com/d3/d3-scale/blob/master/README.md#interpolateMagma) +[plasma](https://github.com/d3/d3-scale/blob/master/README.md#interpolatePlasma) + +4.0 also ships new Cubehelix schemes, including [Dave Green’s default](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCubehelixDefault) and a [cyclical rainbow](https://github.com/d3/d3-scale/blob/master/README.md#interpolateRainbow) inspired by [Matteo Niccoli](https://mycarta.wordpress.com/2013/02/21/perceptual-rainbow-palette-the-method/): + +[cubehelix](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCubehelixDefault) +[rainbow](https://github.com/d3/d3-scale/blob/master/README.md#interpolateRainbow) +[warm](https://github.com/d3/d3-scale/blob/master/README.md#interpolateWarm) +[cool](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCool) + +For even more sequential and categorical color schemes, see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic). + +For an introduction to scales, see [Introducing d3-scale](https://medium.com/@mbostock/introducing-d3-scale-61980c51545f). + +## [Selections (d3-selection)](https://github.com/d3/d3-selection/blob/master/README.md) + +Selections no longer subclass Array using [prototype chain injection](http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/#wrappers_prototype_chain_injection); they are now plain objects, improving performance. The internal fields (*selection*.\_groups, *selection*.\_parents) are private; please use the documented public API to manipulate selections. The new [*selection*.nodes](https://github.com/d3/d3-selection/blob/master/README.md#selection_nodes) method generates an array of all nodes in a selection. + +Selections are now immutable: the elements and parents in a selection never change. (The elements’ attributes and content will of course still be modified!) The [*selection*.sort](https://github.com/d3/d3-selection/blob/master/README.md#selection_sort) and [*selection*.data](https://github.com/d3/d3-selection/blob/master/README.md#selection_data) methods now return new selections rather than modifying the selection in-place. In addition, [*selection*.append](https://github.com/d3/d3-selection/blob/master/README.md#selection_append) no longer merges entering nodes into the update selection; use [*selection*.merge](https://github.com/d3/d3-selection/blob/master/README.md#selection_merge) to combine enter and update after a data join. For example, the following [general update pattern](https://bl.ocks.org/mbostock/a8a5baa4c4a470cda598) in 3.x: + +```js +var circle = svg.selectAll("circle").data(data) // UPDATE + .style("fill", "blue"); + +circle.exit().remove(); // EXIT + +circle.enter().append("circle") // ENTER; modifies UPDATE! 🌶 + .style("fill", "green"); + +circle // ENTER + UPDATE + .style("stroke", "black"); +``` + +Would be rewritten in 4.0 as: + +```js +var circle = svg.selectAll("circle").data(data) // UPDATE + .style("fill", "blue"); + +circle.exit().remove(); // EXIT + +circle.enter().append("circle") // ENTER + .style("fill", "green") + .merge(circle) // ENTER + UPDATE + .style("stroke", "black"); +``` + +This change is discussed further in [What Makes Software Good](https://medium.com/@mbostock/what-makes-software-good-943557f8a488). + +In 3.x, the [*selection*.enter](https://github.com/d3/d3-selection/blob/master/README.md#selection_enter) and [*selection*.exit](https://github.com/d3/d3-selection/blob/master/README.md#selection_exit) methods were undefined until you called *selection*.data, resulting in a TypeError if you attempted to access them. In 4.0, now they simply return the empty selection if the selection has not been joined to data. + +In 3.x, [*selection*.append](https://github.com/d3/d3-selection/blob/master/README.md#selection_append) would always append the new element as the last child of its parent. A little-known trick was to use [*selection*.insert](https://github.com/d3/d3-selection/blob/master/README.md#selection_insert) without specifying a *before* selector when entering nodes, causing the entering nodes to be inserted before the following element in the update selection. In 4.0, this is now the default behavior of *selection*.append; if you do not specify a *before* selector to *selection*.insert, the inserted element is appended as the last child. This change makes the general update pattern preserve the relative order of elements and data. For example, given the following DOM: + +```html +
a
+
b
+
f
+``` + +And the following code: + +```js +var div = d3.select("body").selectAll("div") + .data(["a", "b", "c", "d", "e", "f"], function(d) { return d || this.textContent; }); + +div.enter().append("div") + .text(function(d) { return d; }); +``` + +The resulting DOM will be: + +```html +
a
+
b
+
c
+
d
+
e
+
f
+``` + +Thus, the entering *c*, *d* and *e* are inserted before *f*, since *f* is the following element in the update selection. Although this behavior is sufficient to preserve order if the new data’s order is stable, if the data changes order, you must still use [*selection*.order](https://github.com/d3/d3-selection/blob/master/README.md#selection_order) to reorder elements. + +There is now only one class of selection. 3.x implemented enter selections using a special class with different behavior for *enter*.append and *enter*.select; a consequence of this design was that enter selections in 3.x lacked [certain methods](https://github.com/d3/d3/issues/2043). In 4.0, enter selections are simply normal selections; they have the same methods and the same behavior. Placeholder [enter nodes](https://github.com/d3/d3-selection/blob/master/src/selection/enter.js) now implement [*node*.appendChild](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild), [*node*.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore), [*node*.querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector), and [*node*.querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll). + +The [*selection*.data](https://github.com/d3/d3-selection/blob/master/README.md#selection_data) method has been changed slightly with respect to duplicate keys. In 3.x, if multiple data had the same key, the duplicate data would be ignored and not included in enter, update or exit; in 4.0 the duplicate data is always put in the enter selection. In both 3.x and 4.0, if multiple elements have the same key, the duplicate elements are put in the exit selection. Thus, 4.0’s behavior is now symmetric for enter and exit, and the general update pattern will now produce a DOM that matches the data even if there are duplicate keys. + +Selections have several new methods! Use [*selection*.raise](https://github.com/d3/d3-selection/blob/master/README.md#selection_raise) to move the selected elements to the front of their siblings, so that they are drawn on top; use [*selection*.lower](https://github.com/d3/d3-selection/blob/master/README.md#selection_lower) to move them to the back. Use [*selection*.dispatch](https://github.com/d3/d3-selection/blob/master/README.md#selection_dispatch) to dispatch a [custom event](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) to event listeners. + +When called in getter mode, [*selection*.data](https://github.com/d3/d3-selection/blob/master/README.md#selection_data) now returns the data for all elements in the selection, rather than just the data for the first group of elements. The [*selection*.call](https://github.com/d3/d3-selection/blob/master/README.md#selection_call) method no longer sets the `this` context when invoking the specified function; the *selection* is passed as the first argument to the function, so use that. The [*selection*.on](https://github.com/d3/d3-selection/blob/master/README.md#selection_on) method now accepts multiple whitespace-separated typenames, so you can add or remove multiple listeners simultaneously. For example: + +```js +selection.on("mousedown touchstart", function() { + console.log(d3.event.type); +}); +``` + +The arguments passed to callback functions has changed slightly in 4.0 to be more consistent. The standard arguments are the element’s datum (*d*), the element’s index (*i*), and the element’s group (*nodes*), with *this* as the element. The slight exception to this convention is *selection*.data, which is evaluated for each group rather than each element; it is passed the group’s parent datum (*d*), the group index (*i*), and the selection’s parents (*parents*), with *this* as the group’s parent. + +The new [d3.local](https://github.com/d3/d3-selection/blob/master/README.md#local-variables) provides a mechanism for defining [local variables](https://bl.ocks.org/mbostock/e1192fe405703d8321a5187350910e08): state that is bound to DOM elements, and available to any descendant element. This can be a convenient alternative to using [*selection*.each](https://github.com/d3/d3-selection/blob/master/README.md#selection_each) or storing local state in data. + +The d3.ns.prefix namespace prefix map has been renamed to [d3.namespaces](https://github.com/d3/d3-selection/blob/master/README.md#namespaces), and the d3.ns.qualify method has been renamed to [d3.namespace](https://github.com/d3/d3-selection/blob/master/README.md#namespace). Several new low-level methods are now available, as well. [d3.matcher](https://github.com/d3/d3-selection/blob/master/README.md#matcher) is used internally by [*selection*.filter](https://github.com/d3/d3-selection/blob/master/README.md#selection_filter); [d3.selector](https://github.com/d3/d3-selection/blob/master/README.md#selector) is used by [*selection*.select](https://github.com/d3/d3-selection/blob/master/README.md#selection_select); [d3.selectorAll](https://github.com/d3/d3-selection/blob/master/README.md#selectorAll) is used by [*selection*.selectAll](https://github.com/d3/d3-selection/blob/master/README.md#selection_selectAll); [d3.creator](https://github.com/d3/d3-selection/blob/master/README.md#creator) is used by [*selection*.append](https://github.com/d3/d3-selection/blob/master/README.md#selection_append) and [*selection*.insert](https://github.com/d3/d3-selection/blob/master/README.md#selection_insert). The new [d3.window](https://github.com/d3/d3-selection/blob/master/README.md#window) returns the owner window for a given element, window or document. The new [d3.customEvent](https://github.com/d3/d3-selection/blob/master/README.md#customEvent) temporarily sets [d3.event](https://github.com/d3/d3-selection/blob/master/README.md#event) while invoking a function, allowing you to implement controls which dispatch custom events; this is used by [d3-drag](https://github.com/d3/d3-drag), [d3-zoom](https://github.com/d3/d3-zoom) and [d3-brush](https://github.com/d3/d3-brush). + +For the sake of parsimony, the multi-value methods—where you pass an object to set multiple attributes, styles or properties simultaneously—have been extracted to [d3-selection-multi](https://github.com/d3/d3-selection-multi) and are no longer part of the default bundle. The multi-value map methods have also been renamed to plural form to reduce overload: [*selection*.attrs](https://github.com/d3/d3-selection-multi/blob/master/README.md#selection_attrs), [*selection*.styles](https://github.com/d3/d3-selection-multi/blob/master/README.md#selection_styles) and [*selection*.properties](https://github.com/d3/d3-selection-multi/blob/master/README.md#selection_properties). + +## [Shapes (d3-shape)](https://github.com/d3/d3-shape/blob/master/README.md) + +Pursuant to the great namespace flattening: + +* d3.svg.line ↦ [d3.line](https://github.com/d3/d3-shape/blob/master/README.md#lines) +* d3.svg.line.radial ↦ [d3.radialLine](https://github.com/d3/d3-shape/blob/master/README.md#radialLine) +* d3.svg.area ↦ [d3.area](https://github.com/d3/d3-shape/blob/master/README.md#areas) +* d3.svg.area.radial ↦ [d3.radialArea](https://github.com/d3/d3-shape/blob/master/README.md#radialArea) +* d3.svg.arc ↦ [d3.arc](https://github.com/d3/d3-shape/blob/master/README.md#arcs) +* d3.svg.symbol ↦ [d3.symbol](https://github.com/d3/d3-shape/blob/master/README.md#symbols) +* d3.svg.symbolTypes ↦ [d3.symbolTypes](https://github.com/d3/d3-shape/blob/master/README.md#symbolTypes) +* d3.layout.pie ↦ [d3.pie](https://github.com/d3/d3-shape/blob/master/README.md#pies) +* d3.layout.stack ↦ [d3.stack](https://github.com/d3/d3-shape/blob/master/README.md#stacks) +* d3.svg.diagonal ↦ REMOVED (see [d3/d3-shape#27](https://github.com/d3/d3-shape/issues/27)) +* d3.svg.diagonal.radial ↦ REMOVED + +Shapes are no longer limited to SVG; they can now render to Canvas! Shape generators now support an optional *context*: given a [CanvasRenderingContext2D](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D), you can render a shape as a canvas path to be filled or stroked. For example, a [canvas pie chart](https://bl.ocks.org/mbostock/8878e7fd82034f1d63cf) might use an arc generator: + +```js +var arc = d3.arc() + .outerRadius(radius - 10) + .innerRadius(0) + .context(context); +``` + +To render an arc for a given datum *d*: + +```js +context.beginPath(); +arc(d); +context.fill(); +``` + +See [*line*.context](https://github.com/d3/d3-shape/blob/master/README.md#line_context), [*area*.context](https://github.com/d3/d3-shape/blob/master/README.md#area_context) and [*arc*.context](https://github.com/d3/d3-shape/blob/master/README.md#arc_context) for more. Under the hood, shapes use [d3-path](#paths-d3-path) to serialize canvas path methods to SVG path data when the context is null; thus, shapes are optimized for rendering to canvas. You can also now derive lines from areas. The line shares most of the same accessors, such as [*line*.defined](https://github.com/d3/d3-shape/blob/master/README.md#line_defined) and [*line*.curve](https://github.com/d3/d3-shape/blob/master/README.md#line_curve), with the area from which it is derived. For example, to render the topline of an area, use [*area*.lineY1](https://github.com/d3/d3-shape/blob/master/README.md#area_lineY1); for the baseline, use [*area*.lineY0](https://github.com/d3/d3-shape/blob/master/README.md#area_lineY0). + +4.0 introduces a new curve API for specifying how line and area shapes interpolate between data points. The *line*.interpolate and *area*.interpolate methods have been replaced with [*line*.curve](https://github.com/d3/d3-shape/blob/master/README.md#line_curve) and [*area*.curve](https://github.com/d3/d3-shape/blob/master/README.md#area_curve). Curves are implemented using the [curve interface](https://github.com/d3/d3-shape/blob/master/README.md#custom-curves) rather than as a function that returns an SVG path data string; this allows curves to render to either SVG or Canvas. In addition, *line*.curve and *area*.curve now take a function which instantiates a curve for a given *context*, rather than a string. The full list of equivalents: + +* linear ↦ [d3.curveLinear](https://github.com/d3/d3-shape/blob/master/README.md#curveLinear) +* linear-closed ↦ [d3.curveLinearClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveLinearClosed) +* step ↦ [d3.curveStep](https://github.com/d3/d3-shape/blob/master/README.md#curveStep) +* step-before ↦ [d3.curveStepBefore](https://github.com/d3/d3-shape/blob/master/README.md#curveStepBefore) +* step-after ↦ [d3.curveStepAfter](https://github.com/d3/d3-shape/blob/master/README.md#curveStepAfter) +* basis ↦ [d3.curveBasis](https://github.com/d3/d3-shape/blob/master/README.md#curveBasis) +* basis-open ↦ [d3.curveBasisOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisOpen) +* basis-closed ↦ [d3.curveBasisClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisClosed) +* bundle ↦ [d3.curveBundle](https://github.com/d3/d3-shape/blob/master/README.md#curveBundle) +* cardinal ↦ [d3.curveCardinal](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinal) +* cardinal-open ↦ [d3.curveCardinalOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinalOpen) +* cardinal-closed ↦ [d3.curveCardinalClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinalClosed) +* monotone ↦ [d3.curveMonotoneX](https://github.com/d3/d3-shape/blob/master/README.md#curveMonotoneX) + +But that’s not all! 4.0 now provides parameterized Catmull–Rom splines as proposed by [Yuksel *et al.*](http://www.cemyuksel.com/research/catmullrom_param/). These are available as [d3.curveCatmullRom](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRom), [d3.curveCatmullRomClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRomClosed) and [d3.curveCatmullRomOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRomOpen). + +catmullRom +catmullRomOpen +catmullRomClosed + +Each curve type can define its own named parameters, replacing *line*.tension and *area*.tension. For example, Catmull–Rom splines are parameterized using [*catmullRom*.alpha](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRom_alpha) and defaults to 0.5, which corresponds to a centripetal spline that avoids self-intersections and overshoot. For a uniform Catmull–Rom spline instead: + +```js +var line = d3.line() + .curve(d3.curveCatmullRom.alpha(0)); +``` + +4.0 fixes the interpretation of the cardinal spline *tension* parameter, which is now specified as [*cardinal*.tension](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinal_tension) and defaults to zero for a uniform Catmull–Rom spline; a tension of one produces a linear curve. The first and last segments of basis and cardinal curves have also been fixed! The undocumented *interpolate*.reverse field has been removed. Curves can define different behavior for toplines and baselines by counting the sequence of [*curve*.lineStart](https://github.com/d3/d3-shape/blob/master/README.md#curve_lineStart) within [*curve*.areaStart](https://github.com/d3/d3-shape/blob/master/README.md#curve_areaStart). See the [d3.curveStep implementation](https://github.com/d3/d3-shape/blob/master/src/curve/step.js) for an example. + +4.0 fixes numerous bugs in the monotone curve implementation, and introduces [d3.curveMonotoneY](https://github.com/d3/d3-shape/blob/master/README.md#curveMonotoneY); this is like d3.curveMonotoneX, except it requires that the input points are monotone in *y* rather than *x*, such as for a vertically-oriented line chart. The new [d3.curveNatural](https://github.com/d3/d3-shape/blob/master/README.md#curveNatural) produces a [natural cubic spline](http://mathworld.wolfram.com/CubicSpline.html). The default [β](https://github.com/d3/d3-shape/blob/master/README.md#bundle_beta) for [d3.curveBundle](https://github.com/d3/d3-shape/blob/master/README.md#curveBundle) is now 0.85, rather than 0.7, matching the values used by [Holten](https://www.win.tue.nl/vis1/home/dholten/papers/bundles_infovis.pdf). 4.0 also has a more robust implementation of arc padding; see [*arc*.padAngle](https://github.com/d3/d3-shape/blob/master/README.md#arc_padAngle) and [*arc*.padRadius](https://github.com/d3/d3-shape/blob/master/README.md#arc_padRadius). + +4.0 introduces a new symbol type API. Symbol types are passed to [*symbol*.type](https://github.com/d3/d3-shape/blob/master/README.md#symbol_type) in place of strings. The equivalents are: + +* circle ↦ [d3.symbolCircle](https://github.com/d3/d3-shape/blob/master/README.md#symbolCircle) +* cross ↦ [d3.symbolCross](https://github.com/d3/d3-shape/blob/master/README.md#symbolCross) +* diamond ↦ [d3.symbolDiamond](https://github.com/d3/d3-shape/blob/master/README.md#symbolDiamond) +* square ↦ [d3.symbolSquare](https://github.com/d3/d3-shape/blob/master/README.md#symbolSquare) +* triangle-down ↦ REMOVED +* triangle-up ↦ [d3.symbolTriangle](https://github.com/d3/d3-shape/blob/master/README.md#symbolTriangle) +* ADDED ↦ [d3.symbolStar](https://github.com/d3/d3-shape/blob/master/README.md#symbolStar) +* ADDED ↦ [d3.symbolWye](https://github.com/d3/d3-shape/blob/master/README.md#symbolWye) + +The full set of symbol types is now: + + + +Lastly, 4.0 overhauls the stack layout API, replacing d3.layout.stack with [d3.stack](https://github.com/d3/d3-shape/blob/master/README.md#stacks). The stack generator no longer needs an *x*-accessor. In addition, the API has been simplified: the *stack* generator now accepts tabular input, such as this array of objects: + +```js +var data = [ + {month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400}, + {month: new Date(2015, 1, 1), apples: 1600, bananas: 1440, cherries: 960, dates: 400}, + {month: new Date(2015, 2, 1), apples: 640, bananas: 960, cherries: 640, dates: 400}, + {month: new Date(2015, 3, 1), apples: 320, bananas: 480, cherries: 640, dates: 400} +]; +``` + +To generate the stack layout, first define a stack generator, and then apply it to the data: + +```js +var stack = d3.stack() + .keys(["apples", "bananas", "cherries", "dates"]) + .order(d3.stackOrderNone) + .offset(d3.stackOffsetNone); + +var series = stack(data); +``` + +The resulting array has one element per *series*. Each series has one point per month, and each point has a lower and upper value defining the baseline and topline: + +```js +[ + [[ 0, 3840], [ 0, 1600], [ 0, 640], [ 0, 320]], // apples + [[3840, 5760], [1600, 3040], [ 640, 1600], [ 320, 800]], // bananas + [[5760, 6720], [3040, 4000], [1600, 2240], [ 800, 1440]], // cherries + [[6720, 7120], [4000, 4400], [2240, 2640], [1440, 1840]], // dates +] +``` + +Each series in then typically passed to an [area generator](https://github.com/d3/d3-shape/blob/master/README.md#areas) to render an area chart, or used to construct rectangles for a bar chart. Stack generators no longer modify the input data, so *stack*.out has been removed. + +For an introduction to shapes, see [Introducing d3-shape](https://medium.com/@mbostock/introducing-d3-shape-73f8367e6d12). + +## [Time Formats (d3-time-format)](https://github.com/d3/d3-time-format/blob/master/README.md) + +Pursuant to the great namespace flattening, the format constructors have new names: + +* d3.time.format ↦ [d3.timeFormat](https://github.com/d3/d3-time-format/blob/master/README.md#timeFormat) +* d3.time.format.utc ↦ [d3.utcFormat](https://github.com/d3/d3-time-format/blob/master/README.md#utcFormat) +* d3.time.format.iso ↦ [d3.isoFormat](https://github.com/d3/d3-time-format/blob/master/README.md#isoFormat) + +The *format*.parse method has also been removed in favor of separate [d3.timeParse](https://github.com/d3/d3-time-format/blob/master/README.md#timeParse), [d3.utcParse](https://github.com/d3/d3-time-format/blob/master/README.md#utcParse) and [d3.isoParse](https://github.com/d3/d3-time-format/blob/master/README.md#isoParse) parser constructors. Thus, this code in 3.x: + +```js +var parseTime = d3.time.format("%c").parse; +``` + +Can be rewritten in 4.0 as: + +```js +var parseTime = d3.timeParse("%c"); +``` + +The multi-scale time format d3.time.format.multi has been replaced by [d3.scaleTime](https://github.com/d3/d3-scale/blob/master/README.md#scaleTime)’s [tick format](https://github.com/d3/d3-scale/blob/master/README.md#time_tickFormat). Time formats now coerce inputs to dates, and time parsers coerce inputs to strings. The `%Z` directive now allows more flexible parsing of time zone offsets, such as `-0700`, `-07:00`, `-07`, and `Z`. The `%p` directive is now parsed correctly when the locale’s period name is longer than two characters (*e.g.*, “a.m.”). + +The default U.S. English locale now uses 12-hour time and a more concise representation of the date. This aligns with local convention and is consistent with [*date*.toLocaleString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString) in Chrome, Firefox and Node: + +```js +var now = new Date; +d3.timeFormat("%c")(new Date); // "6/23/2016, 2:01:33 PM" +d3.timeFormat("%x")(new Date); // "6/23/2016" +d3.timeFormat("%X")(new Date); // "2:01:38 PM" +``` + +You can now set the default locale using [d3.timeFormatDefaultLocale](https://github.com/d3/d3-time-format/blob/master/README.md#timeFormatDefaultLocale)! The locales are published as [JSON](https://github.com/d3/d3-request/blob/master/README.md#json) to [npm](https://unpkg.com/d3-time-format/locale/). + +The performance of time formatting and parsing has been improved, and the UTC formatter and parser have a cleaner implementation (that avoids temporarily overriding the Date global). + +## [Time Intervals (d3-time)](https://github.com/d3/d3-time/blob/master/README.md) + +Pursuant to the great namespace flattening, the local time intervals have been renamed: + +* ADDED ↦ [d3.timeMillisecond](https://github.com/d3/d3-time/blob/master/README.md#timeMillisecond) +* d3.time.second ↦ [d3.timeSecond](https://github.com/d3/d3-time/blob/master/README.md#timeSecond) +* d3.time.minute ↦ [d3.timeMinute](https://github.com/d3/d3-time/blob/master/README.md#timeMinute) +* d3.time.hour ↦ [d3.timeHour](https://github.com/d3/d3-time/blob/master/README.md#timeHour) +* d3.time.day ↦ [d3.timeDay](https://github.com/d3/d3-time/blob/master/README.md#timeDay) +* d3.time.sunday ↦ [d3.timeSunday](https://github.com/d3/d3-time/blob/master/README.md#timeSunday) +* d3.time.monday ↦ [d3.timeMonday](https://github.com/d3/d3-time/blob/master/README.md#timeMonday) +* d3.time.tuesday ↦ [d3.timeTuesday](https://github.com/d3/d3-time/blob/master/README.md#timeTuesday) +* d3.time.wednesday ↦ [d3.timeWednesday](https://github.com/d3/d3-time/blob/master/README.md#timeWednesday) +* d3.time.thursday ↦ [d3.timeThursday](https://github.com/d3/d3-time/blob/master/README.md#timeThursday) +* d3.time.friday ↦ [d3.timeFriday](https://github.com/d3/d3-time/blob/master/README.md#timeFriday) +* d3.time.saturday ↦ [d3.timeSaturday](https://github.com/d3/d3-time/blob/master/README.md#timeSaturday) +* d3.time.week ↦ [d3.timeWeek](https://github.com/d3/d3-time/blob/master/README.md#timeWeek) +* d3.time.month ↦ [d3.timeMonth](https://github.com/d3/d3-time/blob/master/README.md#timeMonth) +* d3.time.year ↦ [d3.timeYear](https://github.com/d3/d3-time/blob/master/README.md#timeYear) + +The UTC time intervals have likewise been renamed: + +* ADDED ↦ [d3.utcMillisecond](https://github.com/d3/d3-time/blob/master/README.md#utcMillisecond) +* d3.time.second.utc ↦ [d3.utcSecond](https://github.com/d3/d3-time/blob/master/README.md#utcSecond) +* d3.time.minute.utc ↦ [d3.utcMinute](https://github.com/d3/d3-time/blob/master/README.md#utcMinute) +* d3.time.hour.utc ↦ [d3.utcHour](https://github.com/d3/d3-time/blob/master/README.md#utcHour) +* d3.time.day.utc ↦ [d3.utcDay](https://github.com/d3/d3-time/blob/master/README.md#utcDay) +* d3.time.sunday.utc ↦ [d3.utcSunday](https://github.com/d3/d3-time/blob/master/README.md#utcSunday) +* d3.time.monday.utc ↦ [d3.utcMonday](https://github.com/d3/d3-time/blob/master/README.md#utcMonday) +* d3.time.tuesday.utc ↦ [d3.utcTuesday](https://github.com/d3/d3-time/blob/master/README.md#utcTuesday) +* d3.time.wednesday.utc ↦ [d3.utcWednesday](https://github.com/d3/d3-time/blob/master/README.md#utcWednesday) +* d3.time.thursday.utc ↦ [d3.utcThursday](https://github.com/d3/d3-time/blob/master/README.md#utcThursday) +* d3.time.friday.utc ↦ [d3.utcFriday](https://github.com/d3/d3-time/blob/master/README.md#utcFriday) +* d3.time.saturday.utc ↦ [d3.utcSaturday](https://github.com/d3/d3-time/blob/master/README.md#utcSaturday) +* d3.time.week.utc ↦ [d3.utcWeek](https://github.com/d3/d3-time/blob/master/README.md#utcWeek) +* d3.time.month.utc ↦ [d3.utcMonth](https://github.com/d3/d3-time/blob/master/README.md#utcMonth) +* d3.time.year.utc ↦ [d3.utcYear](https://github.com/d3/d3-time/blob/master/README.md#utcYear) + +The local time range aliases have been renamed: + +* d3.time.seconds ↦ [d3.timeSeconds](https://github.com/d3/d3-time/blob/master/README.md#timeSeconds) +* d3.time.minutes ↦ [d3.timeMinutes](https://github.com/d3/d3-time/blob/master/README.md#timeMinutes) +* d3.time.hours ↦ [d3.timeHours](https://github.com/d3/d3-time/blob/master/README.md#timeHours) +* d3.time.days ↦ [d3.timeDays](https://github.com/d3/d3-time/blob/master/README.md#timeDays) +* d3.time.sundays ↦ [d3.timeSundays](https://github.com/d3/d3-time/blob/master/README.md#timeSundays) +* d3.time.mondays ↦ [d3.timeMondays](https://github.com/d3/d3-time/blob/master/README.md#timeMondays) +* d3.time.tuesdays ↦ [d3.timeTuesdays](https://github.com/d3/d3-time/blob/master/README.md#timeTuesdays) +* d3.time.wednesdays ↦ [d3.timeWednesdays](https://github.com/d3/d3-time/blob/master/README.md#timeWednesdays) +* d3.time.thursdays ↦ [d3.timeThursdays](https://github.com/d3/d3-time/blob/master/README.md#timeThursdays) +* d3.time.fridays ↦ [d3.timeFridays](https://github.com/d3/d3-time/blob/master/README.md#timeFridays) +* d3.time.saturdays ↦ [d3.timeSaturdays](https://github.com/d3/d3-time/blob/master/README.md#timeSaturdays) +* d3.time.weeks ↦ [d3.timeWeeks](https://github.com/d3/d3-time/blob/master/README.md#timeWeeks) +* d3.time.months ↦ [d3.timeMonths](https://github.com/d3/d3-time/blob/master/README.md#timeMonths) +* d3.time.years ↦ [d3.timeYears](https://github.com/d3/d3-time/blob/master/README.md#timeYears) + +The UTC time range aliases have been renamed: + +* d3.time.seconds.utc ↦ [d3.utcSeconds](https://github.com/d3/d3-time/blob/master/README.md#utcSeconds) +* d3.time.minutes.utc ↦ [d3.utcMinutes](https://github.com/d3/d3-time/blob/master/README.md#utcMinutes) +* d3.time.hours.utc ↦ [d3.utcHours](https://github.com/d3/d3-time/blob/master/README.md#utcHours) +* d3.time.days.utc ↦ [d3.utcDays](https://github.com/d3/d3-time/blob/master/README.md#utcDays) +* d3.time.sundays.utc ↦ [d3.utcSundays](https://github.com/d3/d3-time/blob/master/README.md#utcSundays) +* d3.time.mondays.utc ↦ [d3.utcMondays](https://github.com/d3/d3-time/blob/master/README.md#utcMondays) +* d3.time.tuesdays.utc ↦ [d3.utcTuesdays](https://github.com/d3/d3-time/blob/master/README.md#utcTuesdays) +* d3.time.wednesdays.utc ↦ [d3.utcWednesdays](https://github.com/d3/d3-time/blob/master/README.md#utcWednesdays) +* d3.time.thursdays.utc ↦ [d3.utcThursdays](https://github.com/d3/d3-time/blob/master/README.md#utcThursdays) +* d3.time.fridays.utc ↦ [d3.utcFridays](https://github.com/d3/d3-time/blob/master/README.md#utcFridays) +* d3.time.saturdays.utc ↦ [d3.utcSaturdays](https://github.com/d3/d3-time/blob/master/README.md#utcSaturdays) +* d3.time.weeks.utc ↦ [d3.utcWeeks](https://github.com/d3/d3-time/blob/master/README.md#utcWeeks) +* d3.time.months.utc ↦ [d3.utcMonths](https://github.com/d3/d3-time/blob/master/README.md#utcMonths) +* d3.time.years.utc ↦ [d3.utcYears](https://github.com/d3/d3-time/blob/master/README.md#utcYears) + +The behavior of [*interval*.range](https://github.com/d3/d3-time/blob/master/README.md#interval_range) (and the convenience aliases such as [d3.timeDays](https://github.com/d3/d3-time/blob/master/README.md#timeDays)) has been changed when *step* is greater than one. Rather than filtering the returned dates using the field number, *interval*.range now behaves like [d3.range](https://github.com/d3/d3-array/blob/master/README.md#range): it simply skips, returning every *step*th date. For example, the following code in 3.x returns only odd days of the month: + +```js +d3.time.days(new Date(2016, 4, 28), new Date(2016, 5, 5), 2); +// [Sun May 29 2016 00:00:00 GMT-0700 (PDT), +// Tue May 31 2016 00:00:00 GMT-0700 (PDT), +// Wed Jun 01 2016 00:00:00 GMT-0700 (PDT), +// Fri Jun 03 2016 00:00:00 GMT-0700 (PDT)] +``` + +Note the returned array of dates does not start on the *start* date because May 28 is even. Also note that May 31 and June 1 are one day apart, not two! The behavior of d3.timeDays in 4.0 is probably closer to what you expect: + +```js +d3.timeDays(new Date(2016, 4, 28), new Date(2016, 5, 5), 2); +// [Sat May 28 2016 00:00:00 GMT-0700 (PDT), +// Mon May 30 2016 00:00:00 GMT-0700 (PDT), +// Wed Jun 01 2016 00:00:00 GMT-0700 (PDT), +// Fri Jun 03 2016 00:00:00 GMT-0700 (PDT)] +``` + +If you want a filtered view of a time interval (say to guarantee that two overlapping ranges are consistent, such as when generating [time scale ticks](https://github.com/d3/d3-scale/blob/master/README.md#time_ticks)), you can use the new [*interval*.every](https://github.com/d3/d3-time/blob/master/README.md#interval_every) method or its more general cousin [*interval*.filter](https://github.com/d3/d3-time/blob/master/README.md#interval_filter): + +```js +d3.timeDay.every(2).range(new Date(2016, 4, 28), new Date(2016, 5, 5)); +// [Sun May 29 2016 00:00:00 GMT-0700 (PDT), +// Tue May 31 2016 00:00:00 GMT-0700 (PDT), +// Wed Jun 01 2016 00:00:00 GMT-0700 (PDT), +// Fri Jun 03 2016 00:00:00 GMT-0700 (PDT)] +``` + +Time intervals now expose an [*interval*.count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) method for counting the number of interval boundaries after a *start* date and before or equal to an *end* date. This replaces d3.time.dayOfYear and related methods in 3.x. For example, this code in 3.x: + +```js +var now = new Date; +d3.time.dayOfYear(now); // 165 +``` + +Can be rewritten in 4.0 as: + +```js +var now = new Date; +d3.timeDay.count(d3.timeYear(now), now); // 165 +``` + +Likewise, in place of 3.x’s d3.time.weekOfYear, in 4.0 you would say: + +```js +d3.timeWeek.count(d3.timeYear(now), now); // 24 +``` + +The new *interval*.count is of course more general. For example, you can use it to compute hour-of-week for a heatmap: + +```js +d3.timeHour.count(d3.timeWeek(now), now); // 64 +``` + +Here are all the equivalences from 3.x to 4.0: + +* d3.time.dayOfYear ↦ [d3.timeDay](https://github.com/d3/d3-time/blob/master/README.md#timeDay).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.sundayOfYear ↦ [d3.timeSunday](https://github.com/d3/d3-time/blob/master/README.md#timeSunday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.mondayOfYear ↦ [d3.timeMonday](https://github.com/d3/d3-time/blob/master/README.md#timeMonday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.tuesdayOfYear ↦ [d3.timeTuesday](https://github.com/d3/d3-time/blob/master/README.md#timeTuesday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.wednesdayOfYear ↦ [d3.timeWednesday](https://github.com/d3/d3-time/blob/master/README.md#timeWednesday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.thursdayOfYear ↦ [d3.timeThursday](https://github.com/d3/d3-time/blob/master/README.md#timeThursday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.fridayOfYear ↦ [d3.timeFriday](https://github.com/d3/d3-time/blob/master/README.md#timeFriday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.saturdayOfYear ↦ [d3.timeSaturday](https://github.com/d3/d3-time/blob/master/README.md#timeSaturday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.weekOfYear ↦ [d3.timeWeek](https://github.com/d3/d3-time/blob/master/README.md#timeWeek).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.dayOfYear.utc ↦ [d3.utcDay](https://github.com/d3/d3-time/blob/master/README.md#utcDay).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.sundayOfYear.utc ↦ [d3.utcSunday](https://github.com/d3/d3-time/blob/master/README.md#utcSunday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.mondayOfYear.utc ↦ [d3.utcMonday](https://github.com/d3/d3-time/blob/master/README.md#utcMonday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.tuesdayOfYear.utc ↦ [d3.utcTuesday](https://github.com/d3/d3-time/blob/master/README.md#utcTuesday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.wednesdayOfYear.utc ↦ [d3.utcWednesday](https://github.com/d3/d3-time/blob/master/README.md#utcWednesday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.thursdayOfYear.utc ↦ [d3.utcThursday](https://github.com/d3/d3-time/blob/master/README.md#utcThursday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.fridayOfYear.utc ↦ [d3.utcFriday](https://github.com/d3/d3-time/blob/master/README.md#utcFriday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.saturdayOfYear.utc ↦ [d3.utcSaturday](https://github.com/d3/d3-time/blob/master/README.md#utcSaturday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) +* d3.time.weekOfYear.utc ↦ [d3.utcWeek](https://github.com/d3/d3-time/blob/master/README.md#utcWeek).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) + +D3 4.0 now also lets you define custom time intervals using [d3.timeInterval](https://github.com/d3/d3-time/blob/master/README.md#timeInterval). The [d3.timeYear](https://github.com/d3/d3-time/blob/master/README.md#timeYear), [d3.utcYear](https://github.com/d3/d3-time/blob/master/README.md#utcYear), [d3.timeMillisecond](https://github.com/d3/d3-time/blob/master/README.md#timeMillisecond) and [d3.utcMillisecond](https://github.com/d3/d3-time/blob/master/README.md#utcMillisecond) intervals have optimized implementations of [*interval*.every](https://github.com/d3/d3-time/blob/master/README.md#interval_every), which is necessary to generate time ticks for very large or very small domains efficiently. More generally, the performance of time intervals has been improved, and time intervals now do a better job with respect to daylight savings in various locales. + +## [Timers (d3-timer)](https://github.com/d3/d3-timer/blob/master/README.md) + +In D3 3.x, the only way to stop a timer was for its callback to return true. For example, this timer stops after one second: + +```js +d3.timer(function(elapsed) { + console.log(elapsed); + return elapsed >= 1000; +}); +``` + +In 4.0, use [*timer*.stop](https://github.com/d3/d3-timer/blob/master/README.md#timer_stop) instead: + +```js +var t = d3.timer(function(elapsed) { + console.log(elapsed); + if (elapsed >= 1000) { + t.stop(); + } +}); +``` + +The primary benefit of *timer*.stop is that timers are not required to self-terminate: they can be stopped externally, allowing for the immediate and synchronous disposal of associated resources, and the separation of concerns. The above is equivalent to: + +```js +var t = d3.timer(function(elapsed) { + console.log(elapsed); +}); + +d3.timeout(function() { + t.stop(); +}, 1000); +``` + +This improvement extends to [d3-transition](#transitions-d3-transition): now when a transition is interrupted, its resources are immediately freed rather than having to wait for transition to start. + +4.0 also introduces a new [*timer*.restart](https://github.com/d3/d3-timer/blob/master/README.md#timer_restart) method for restarting timers, for replacing the callback of a running timer, or for changing its delay or reference time. Unlike *timer*.stop followed by [d3.timer](https://github.com/d3/d3-timer/blob/master/README.md#timer), *timer*.restart maintains the invocation priority of an existing timer: it guarantees that the order of invocation of active timers remains the same. The d3.timer.flush method has been renamed to [d3.timerFlush](https://github.com/d3/d3-timer/blob/master/README.md#timerFlush). + +Some usage patterns in D3 3.x could cause the browser to hang when a background page returned to the foreground. For example, the following code schedules a transition every second: + +```js +setInterval(function() { + d3.selectAll("div").transition().call(someAnimation); // BAD +}, 1000); +``` + +If such code runs in the background for hours, thousands of queued transitions will try to run simultaneously when the page is foregrounded. D3 4.0 avoids this hang by freezing time in the background: when a page is in the background, time does not advance, and so no queue of timers accumulates to run when the page returns to the foreground. Use d3.timer instead of transitions to schedule a long-running animation, or use [d3.timeout](https://github.com/d3/d3-timer/blob/master/README.md#timeout) and [d3.interval](https://github.com/d3/d3-timer/blob/master/README.md#interval) in place of setTimeout and setInterval to prevent transitions from being queued in the background: + +```js +d3.interval(function() { + d3.selectAll("div").transition().call(someAnimation); // GOOD +}, 1000); +``` + +By freezing time in the background, timers are effectively “unaware” of being backgrounded. It’s like nothing happened! 4.0 also now uses high-precision time ([performance.now](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now)) where available; the current time is available as [d3.now](https://github.com/d3/d3-timer/blob/master/README.md#now). + +## [Transitions (d3-transition)](https://github.com/d3/d3-transition/blob/master/README.md) + +The [*selection*.transition](https://github.com/d3/d3-transition/blob/master/README.md#selection_transition) method now takes an optional *transition* instance which can be used to synchronize a new transition with an existing transition. (This change is discussed further in [What Makes Software Good?](https://medium.com/@mbostock/what-makes-software-good-943557f8a488)) For example: + +```js +var t = d3.transition() + .duration(750) + .ease(d3.easeLinear); + +d3.selectAll(".apple").transition(t) + .style("fill", "red"); + +d3.selectAll(".orange").transition(t) + .style("fill", "orange"); +``` + +Transitions created this way inherit timing from the closest ancestor element, and thus are synchronized even when the referenced *transition* has variable timing such as a staggered delay. This method replaces the deeply magical behavior of *transition*.each in 3.x; in 4.0, [*transition*.each](https://github.com/d3/d3-transition/blob/master/README.md#transition_each) is identical to [*selection*.each](https://github.com/d3/d3-selection/blob/master/README.md#selection_each). Use the new [*transition*.on](https://github.com/d3/d3-transition/blob/master/README.md#transition_on) method to listen to transition events. + +The meaning of [*transition*.delay](https://github.com/d3/d3-transition/blob/master/README.md#transition_delay) has changed for chained transitions created by [*transition*.transition](https://github.com/d3/d3-transition/blob/master/README.md#transition_transition). The specified delay is now relative to the *previous* transition in the chain, rather than the *first* transition in the chain; this makes it easier to insert interstitial pauses. For example: + +```js +d3.selectAll(".apple") + .transition() // First fade to green. + .style("fill", "green") + .transition() // Then red. + .style("fill", "red") + .transition() // Wait one second. Then brown, and remove. + .delay(1000) + .style("fill", "brown") + .remove(); +``` + +Time is now frozen in the background; see [d3-timer](#timers-d3-timer) for more information. While it was previously the case that transitions did not run in the background, now they pick up where they left off when the page returns to the foreground. This avoids page hangs by not scheduling an unbounded number of transitions in the background. If you want to schedule an infinitely-repeating transition, use transition events, or use [d3.timeout](https://github.com/d3/d3-timer/blob/master/README.md#timeout) and [d3.interval](https://github.com/d3/d3-timer/blob/master/README.md#interval) in place of [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) and [setInterval](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval). + +The [*selection*.interrupt](https://github.com/d3/d3-transition/blob/master/README.md#selection_interrupt) method now cancels all scheduled transitions on the selected elements, in addition to interrupting any active transition. When transitions are interrupted, any resources associated with the transition are now released immediately, rather than waiting until the transition starts, improving performance. (See also [*timer*.stop](https://github.com/d3/d3-timer/blob/master/README.md#timer_stop).) The new [d3.interrupt](https://github.com/d3/d3-transition/blob/master/README.md#interrupt) method is an alternative to [*selection*.interrupt](https://github.com/d3/d3-transition/blob/master/README.md#selection_interrupt) for quickly interrupting a single node. + +The new [d3.active](https://github.com/d3/d3-transition/blob/master/README.md#active) method allows you to select the currently-active transition on a given *node*, if any. This is useful for modifying in-progress transitions and for scheduling infinitely-repeating transitions. For example, this transition continuously oscillates between red and blue: + +```js +d3.select("circle") + .transition() + .on("start", function repeat() { + d3.active(this) + .style("fill", "red") + .transition() + .style("fill", "blue") + .transition() + .on("start", repeat); + }); +``` + +The [life cycle of a transition](https://github.com/d3/d3-transition/blob/master/README.md#the-life-of-a-transition) is now more formally defined and enforced. For example, attempting to change the duration of a running transition now throws an error rather than silently failing. The [*transition*.remove](https://github.com/d3/d3-transition/blob/master/README.md#transition_remove) method has been fixed if multiple transition names are in use: the element is only removed if it has no scheduled transitions, regardless of name. The [*transition*.ease](https://github.com/d3/d3-transition/blob/master/README.md#transition_ease) method now always takes an [easing function](#easings-d3-ease), not a string. When a transition ends, the tweens are invoked one last time with *t* equal to exactly 1, regardless of the associated easing function. + +As with [selections](#selections-d3-selection) in 4.0, all transition callback functions now receive the standard arguments: the element’s datum (*d*), the element’s index (*i*), and the element’s group (*nodes*), with *this* as the element. This notably affects [*transition*.attrTween](https://github.com/d3/d3-transition/blob/master/README.md#transition_attrTween) and [*transition*.styleTween](https://github.com/d3/d3-transition/blob/master/README.md#transition_styleTween), which no longer pass the *tween* function the current attribute or style value as the third argument. The *transition*.attrTween and *transition*.styleTween methods can now be called in getter modes for debugging or to share tween definitions between transitions. + +Homogenous transitions are now optimized! If all elements in a transition share the same tween, interpolator, or event listeners, this state is now shared across the transition rather than separately allocated for each element. 4.0 also uses an optimized default interpolator in place of [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) for [*transition*.attr](https://github.com/d3/d3-transition/blob/master/README.md#transition_attr) and [*transition*.style](https://github.com/d3/d3-transition/blob/master/README.md#transition_style). And transitions can now interpolate both [CSS](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformCss) and [SVG](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformSvg) transforms. + +For reusable components that support transitions, such as [axes](#axes-d3-axis), a new [*transition*.selection](https://github.com/d3/d3-transition/blob/master/README.md#transition_selection) method returns the [selection](#selections-d3-selection) that corresponds to a given transition. There is also a new [*transition*.merge](https://github.com/d3/d3-transition/blob/master/README.md#transition_merge) method that is equivalent to [*selection*.merge](https://github.com/d3/d3-selection/blob/master/README.md#selection_merge). + +For the sake of parsimony, the multi-value map methods have been extracted to [d3-selection-multi](https://github.com/d3/d3-selection-multi) and are no longer part of the default bundle. The multi-value map methods have also been renamed to plural form to reduce overload: [*transition*.attrs](https://github.com/d3/d3-selection-multi/blob/master/README.md#transition_attrs) and [*transition*.styles](https://github.com/d3/d3-selection-multi/blob/master/README.md#transition_styles). + +## [Voronoi Diagrams (d3-voronoi)](https://github.com/d3/d3-voronoi/blob/master/README.md) + +The d3.geom.voronoi method has been renamed to [d3.voronoi](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi), and the *voronoi*.clipExtent method has been renamed to [*voronoi*.extent](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_extent). The undocumented *polygon*.point property in 3.x, which is the element in the input *data* corresponding to the polygon, has been renamed to *polygon*.data. + +Calling [*voronoi*](https://github.com/d3/d3-voronoi/blob/master/README.md#_voronoi) now returns the full [Voronoi diagram](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi-diagrams), which includes topological information: each Voronoi edge exposes *edge*.left and *edge*.right specifying the sites on either side of the edge, and each Voronoi cell is defined as an array of these edges and a corresponding site. The Voronoi diagram can be used to efficiently compute both the Voronoi and Delaunay tessellations for a set of points: [*diagram*.polygons](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_polygons), [*diagram*.links](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_links), and [*diagram*.triangles](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_triangles). The new topology is also useful in conjunction with TopoJSON; see the [Voronoi topology example](https://bl.ocks.org/mbostock/cd52a201d7694eb9d890). + +The [*voronoi*.polygons](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_polygons) and [*diagram*.polygons](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_polygons) now require an [extent](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_extent); there is no longer an implicit extent of ±1e6. The [*voronoi*.links](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_links), [*voronoi*.triangles](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_triangles), [*diagram*.links](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_links) and [*diagram*.triangles](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_triangles) are now affected by the clip extent: as the Delaunay is computed as the dual of the Voronoi, two sites are only linked if the clipped cells are touching. To compute the Delaunay triangulation without respect to clipping, set the extent to null. + +The Voronoi generator finally has well-defined behavior for coincident vertices: the first of a set of coincident points has a defined cell, while the subsequent duplicate points have null cells. The returned array of polygons is sparse, so by using *array*.forEach or *array*.map, you can easily skip undefined cells. The Voronoi generator also now correctly handles the case where no cell edges intersect the extent. + +## [Zooming (d3-zoom)](https://github.com/d3/d3-zoom/blob/master/README.md) + +The zoom behavior d3.behavior.zoom has been renamed to d3.zoom. Zoom behaviors no longer store the active zoom transform (*i.e.*, the visible region; the scale and translate) internally. The zoom transform is now stored on any elements to which the zoom behavior has been applied. The zoom transform is available as *event*.transform within a zoom event or by calling [d3.zoomTransform](https://github.com/d3/d3-zoom/blob/master/README.md#zoomTransform) on a given *element*. To zoom programmatically, use [*zoom*.transform](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_transform) with a given [selection](#selections-d3-selection) or [transition](#transitions-d3-transition); see the [zoom transitions example](https://bl.ocks.org/mbostock/b783fbb2e673561d214e09c7fb5cedee). The *zoom*.event method has been removed. + +To make programmatic zooming easier, there are several new convenience methods on top of *zoom*.transform: [*zoom*.translateBy](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_translateBy), [*zoom*.scaleBy](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleBy) and [*zoom*.scaleTo](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleTo). There is also a new API for describing [zoom transforms](https://github.com/d3/d3-zoom/blob/master/README.md#zoom-transforms). Zoom behaviors are no longer dependent on [scales](#scales-d3-scale), but you can use [*transform*.rescaleX](https://github.com/d3/d3-zoom/blob/master/README.md#transform_rescaleX), [*transform*.rescaleY](https://github.com/d3/d3-zoom/blob/master/README.md#transform_rescaleY), [*transform*.invertX](https://github.com/d3/d3-zoom/blob/master/README.md#transform_invertX) or [*transform*.invertY](https://github.com/d3/d3-zoom/blob/master/README.md#transform_invertY) to transform a scale’s domain. 3.x’s *event*.scale is replaced with *event*.transform.k, and *event*.translate is replaced with *event*.transform.x and *event*.transform.y. The *zoom*.center method has been removed in favor of programmatic zooming. + +The zoom behavior finally supports simple constraints on panning! The new [*zoom*.translateExtent](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_translateExtent) lets you define the viewable extent of the world: the currently-visible extent (the extent of the viewport, as defined by [*zoom*.extent](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_extent)) is always contained within the translate extent. The *zoom*.size method has been replaced by *zoom*.extent, and the default behavior is now smarter: it defaults to the extent of the zoom behavior’s owner element, rather than being hardcoded to 960×500. (This also improves the default path chosen during smooth zoom transitions!) + +The zoom behavior’s interaction has also improved. It now correctly handles concurrent wheeling and dragging, as well as concurrent touching and mousing. The zoom behavior now ignores wheel events at the limits of its scale extent, allowing you to scroll past a zoomable area. The *zoomstart* and *zoomend* events have been renamed *start* and *end*. By default, zoom behaviors now ignore right-clicks intended for the context menu; use [*zoom*.filter](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_filter) to control which events are ignored. The zoom behavior also ignores emulated mouse events on iOS. The zoom behavior now consumes handled events, making it easier to combine with other interactive behaviors such as [dragging](#dragging-d3-drag). diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 00000000000000..0b791d099a6322 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,12 @@ +STOP. DO NOT ASK FOR HELP HERE! + +If you ignore this message and ask for help anyway, your issue will be closed without a response. + +If you want help, please try one of the following forums instead: + +Stack Overflow: https://stackoverflow.com/questions/tagged/d3.js +Slack: https://d3-slackin.herokuapp.com/ +Google Groups: https://groups.google.com/d/forum/d3-js +Observable: https://observablehq.com/@d3 + +ARE YOU REPORTING A BUG, OR MAKING A FEATURE REQUEST? Please file an issue on the relevant D3 module, not here; see https://github.com/d3. Please isolate the specific methods that exhibit unexpected behavior and precisely describe how your expectations were not met. diff --git a/LICENSE b/LICENSE index 0bc47f33ef3284..894ddc6549f17d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,8 @@ -Copyright (c) 2013, Michael Bostock +Copyright 2010-2020 Mike Bostock All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. @@ -11,16 +11,17 @@ modification, are permitted provided that the following conditions are met: this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -* The name Michael Bostock may not be used to endorse or promote products - derived from this software without specific prior written permission. +* Neither the name of the author nor the names of contributors may be used to + endorse or promote products derived from this software without specific prior + written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile deleted file mode 100644 index d5511ea197d924..00000000000000 --- a/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -LOCALE ?= en_US - -GENERATED_FILES = \ - d3.js \ - d3.min.js \ - src/format/format-localized.js \ - src/time/format-localized.js \ - bower.json \ - component.json - -all: $(GENERATED_FILES) - -.PHONY: clean all test - -test: - @npm test - -benchmark: all - @node test/geo/benchmark.js - -src/format/format-localized.js: bin/locale src/format/format-locale.js - LC_NUMERIC=$(LOCALE) LC_MONETARY=$(LOCALE) locale -ck LC_NUMERIC LC_MONETARY | bin/locale src/format/format-locale.js > $@ - -src/time/format-localized.js: bin/locale src/time/format-locale.js - LC_TIME=$(LOCALE) locale -ck LC_TIME | bin/locale src/time/format-locale.js > $@ - -src/start.js: package.json bin/start - bin/start > $@ - -d3.js: $(shell node_modules/.bin/smash --list src/d3.js) package.json - @rm -f $@ - node_modules/.bin/smash src/d3.js | node_modules/.bin/uglifyjs - -b indent-level=2 -o $@ - @chmod a-w $@ - -d3.min.js: d3.js bin/uglify - @rm -f $@ - bin/uglify $< > $@ - -%.json: bin/% package.json - @rm -f $@ - bin/$* > $@ - @chmod a-w $@ - -clean: - rm -f -- $(GENERATED_FILES) diff --git a/README.md b/README.md index 885069c70bfc53..74058319051108 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,57 @@ -# Data-Driven Documents +# D3: Data-Driven Documents -**D3.js** is a JavaScript library for manipulating documents based on data. **D3** helps you bring data to life using HTML, SVG and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation. + -Want to learn more? [See the wiki.](https://github.com/mbostock/d3/wiki) +**D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data. -For examples, [see the gallery](https://github.com/mbostock/d3/wiki/Gallery) and [mbostock’s bl.ocks](http://bl.ocks.org/mbostock). +## Resources + +* [Introduction](https://observablehq.com/@d3/learn-d3) +* [API Reference](https://github.com/d3/d3/blob/master/API.md) +* [Releases](https://github.com/d3/d3/releases) +* [Examples](https://observablehq.com/@d3/gallery) +* [Wiki](https://github.com/d3/d3/wiki) + +## Installing + +If you use npm, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [unpkg](https://unpkg.com/d3/). For example: + +```html + +``` + +For the minified version: + +```html + +``` + +You can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection): + +```html + +``` + +D3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules: + +```js +import {scaleLinear} from "d3-scale"; +``` + +Or import everything into a namespace (here, `d3`): + +```js +import * as d3 from "d3"; +``` + +In Node: + +```js +const d3 = require("d3"); +``` + +You can also require individual modules and combine them into a `d3` object using [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): + +```js +const d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection")); +``` diff --git a/bin/bower b/bin/bower deleted file mode 100755 index ea23efc35d6da0..00000000000000 --- a/bin/bower +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env node - -var fs = require("fs"); - -console.log(JSON.stringify({ - "name": "d3", - "version": require("../package.json").version, - "main": "d3.js", - "scripts": [ - "d3.js" - ], - "ignore": [ - ".DS_Store", - ".git", - ".gitignore", - ".npmignore", - ".travis.yml", - "Makefile", - "bin", - "component.json", - "index-browserify.js", - "index.js", - "lib", - "node_modules", - "package.json", - "src", - "test" - ] -}, null, 2)); diff --git a/bin/component b/bin/component deleted file mode 100755 index 507b0ac93fcc0c..00000000000000 --- a/bin/component +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env node - -var fs = require("fs"), - package = require("../package.json"); - -console.log(JSON.stringify({ - "name": "d3", - "repo": "mbostock/d3", - "description": package.description, - "keywords": package.keywords, - "version": package.version, - "main": "index-browserify.js", - "scripts": [ - "d3.js", - "index-browserify.js" - ], - "dependencies": {}, - "development": {}, - "license": package.licenses[0].type -}, null, 2)); diff --git a/bin/locale b/bin/locale deleted file mode 100755 index 96548753a4ecac..00000000000000 --- a/bin/locale +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env node - -var fs = require("fs"), - puts = require("util").puts, - formats = {}, - kvRe = /=/, - valueRe = /;/g, - quotedRe = /"([^"]*?)"/g, - data = []; - -process.stdin.resume(); -process.stdin.setEncoding("utf8"); -process.stdin.on("data", function(chunk) { data.push(chunk); }); -process.stdin.on("end", write); - -function write() { - data.join("\n").split(/\n/g).forEach(function(line) { - var i = line.match(kvRe); - if (i && (i = i.index)) { - var value = line.substring(i + 1).replace(quotedRe, "$1").split(valueRe); - formats[line.substring(0, i)] = value; - } - }); - - puts(fs.readFileSync(process.argv[2], "utf8").replace(/\{([a-z_]+)\}/g, function(d, k) { - d = formats[k]; - return k === "grouping" - ? d === "127" || d === "0" ? null : "[" + d.map(Number).join(", ") + "]" - : d == null ? null : d.length > 1 ? "[" + d.map(quote).join(", ") + "]" : quote(d[0]); - })); -} - -function quote(d) { return '"' + d + '"'; } diff --git a/bin/start b/bin/start deleted file mode 100755 index b2c351861283fb..00000000000000 --- a/bin/start +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -console.log("d3 = (function(){\n var d3 = {version: " + JSON.stringify(require("../package.json").version) + "}; // semver"); diff --git a/bin/uglify b/bin/uglify deleted file mode 100755 index c8b307e9111dff..00000000000000 --- a/bin/uglify +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env node - -var fs = require("fs"), - uglify = require("uglify-js"); - -var filename = process.argv[2], - toplevel = uglify.parse(fs.readFileSync(filename, "utf8"), {filename: filename}), - output = uglify.OutputStream({ascii_only: true}), - compressor = uglify.Compressor(true), - warn = uglify.AST_Node.warn; - -uglify.AST_Node.warn = function(s, o) { - if (o.msg === "Accidental global?" && o.name === "d3" && o.line === 1 && !o.col) return; - warn.apply(this, arguments); -}; - -toplevel.figure_out_scope(); -toplevel.scope_warnings({ - undeclared: false, - unreferenced: false, - assign_to_global: true, - func_arguments: false, - nested_defuns: false, - eval: false -}); - -toplevel = toplevel.transform(compressor); - -toplevel.figure_out_scope(); -toplevel.compute_char_frequency(true); -toplevel.mangle_names(true); -toplevel.print(output); - -require("util").print(output.get()); diff --git a/bower.json b/bower.json deleted file mode 100644 index 21edd9e96ae5ed..00000000000000 --- a/bower.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "d3", - "version": "3.3.5", - "main": "d3.js", - "scripts": [ - "d3.js" - ], - "ignore": [ - ".DS_Store", - ".git", - ".gitignore", - ".npmignore", - ".travis.yml", - "Makefile", - "bin", - "component.json", - "index-browserify.js", - "index.js", - "lib", - "node_modules", - "package.json", - "src", - "test" - ] -} diff --git a/component.json b/component.json deleted file mode 100644 index 8d48f152c3911c..00000000000000 --- a/component.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "d3", - "repo": "mbostock/d3", - "description": "A small, free JavaScript library for manipulating documents based on data.", - "keywords": [ - "dom", - "w3c", - "visualization", - "svg", - "animation", - "canvas" - ], - "version": "3.3.5", - "main": "index-browserify.js", - "scripts": [ - "d3.js", - "index-browserify.js" - ], - "dependencies": {}, - "development": {}, - "license": "BSD" -} diff --git a/d3.js b/d3.js deleted file mode 100644 index b32ce5f0db746e..00000000000000 --- a/d3.js +++ /dev/null @@ -1,8978 +0,0 @@ -d3 = function() { - var d3 = { - version: "3.3.5" - }; - if (!Date.now) Date.now = function() { - return +new Date(); - }; - var d3_arraySlice = [].slice, d3_array = function(list) { - return d3_arraySlice.call(list); - }; - var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window; - try { - d3_array(d3_documentElement.childNodes)[0].nodeType; - } catch (e) { - d3_array = function(list) { - var i = list.length, array = new Array(i); - while (i--) array[i] = list[i]; - return array; - }; - } - try { - d3_document.createElement("div").style.setProperty("opacity", 0, ""); - } catch (error) { - var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; - d3_element_prototype.setAttribute = function(name, value) { - d3_element_setAttribute.call(this, name, value + ""); - }; - d3_element_prototype.setAttributeNS = function(space, local, value) { - d3_element_setAttributeNS.call(this, space, local, value + ""); - }; - d3_style_prototype.setProperty = function(name, value, priority) { - d3_style_setProperty.call(this, name, value + "", priority); - }; - } - d3.ascending = function(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - }; - d3.descending = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; - }; - d3.min = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && a > b) a = b; - } else { - while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; - } - return a; - }; - d3.max = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && b > a) a = b; - } else { - while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; - } - return a; - }; - d3.extent = function(array, f) { - var i = -1, n = array.length, a, b, c; - if (arguments.length === 1) { - while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined; - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } else { - while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } - return [ a, c ]; - }; - d3.sum = function(array, f) { - var s = 0, n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (!isNaN(a = +array[i])) s += a; - } else { - while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; - } - return s; - }; - function d3_number(x) { - return x != null && !isNaN(x); - } - d3.mean = function(array, f) { - var n = array.length, a, m = 0, i = -1, j = 0; - if (arguments.length === 1) { - while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; - } else { - while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; - } - return j ? m : undefined; - }; - d3.quantile = function(values, p) { - var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; - return e ? v + e * (values[h] - v) : v; - }; - d3.median = function(array, f) { - if (arguments.length > 1) array = array.map(f); - array = array.filter(d3_number); - return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined; - }; - d3.bisector = function(f) { - return { - left: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (f.call(a, a[mid], mid) < x) lo = mid + 1; else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (x < f.call(a, a[mid], mid)) hi = mid; else lo = mid + 1; - } - return lo; - } - }; - }; - var d3_bisector = d3.bisector(function(d) { - return d; - }); - d3.bisectLeft = d3_bisector.left; - d3.bisect = d3.bisectRight = d3_bisector.right; - d3.shuffle = function(array) { - var m = array.length, t, i; - while (m) { - i = Math.random() * m-- | 0; - t = array[m], array[m] = array[i], array[i] = t; - } - return array; - }; - d3.permute = function(array, indexes) { - var i = indexes.length, permutes = new Array(i); - while (i--) permutes[i] = array[indexes[i]]; - return permutes; - }; - d3.pairs = function(array) { - var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); - while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; - return pairs; - }; - d3.zip = function() { - if (!(n = arguments.length)) return []; - for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { - for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { - zip[j] = arguments[j][i]; - } - } - return zips; - }; - function d3_zipLength(d) { - return d.length; - } - d3.transpose = function(matrix) { - return d3.zip.apply(d3, matrix); - }; - d3.keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; - }; - d3.values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; - }; - d3.entries = function(map) { - var entries = []; - for (var key in map) entries.push({ - key: key, - value: map[key] - }); - return entries; - }; - d3.merge = function(arrays) { - return Array.prototype.concat.apply([], arrays); - }; - d3.range = function(start, stop, step) { - if (arguments.length < 3) { - step = 1; - if (arguments.length < 2) { - stop = start; - start = 0; - } - } - if ((stop - start) / step === Infinity) throw new Error("infinite range"); - var range = [], k = d3_range_integerScale(Math.abs(step)), i = -1, j; - start *= k, stop *= k, step *= k; - if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); - return range; - }; - function d3_range_integerScale(x) { - var k = 1; - while (x * k % 1) k *= 10; - return k; - } - function d3_class(ctor, properties) { - try { - for (var key in properties) { - Object.defineProperty(ctor.prototype, key, { - value: properties[key], - enumerable: false - }); - } - } catch (e) { - ctor.prototype = properties; - } - } - d3.map = function(object) { - var map = new d3_Map(); - if (object instanceof d3_Map) object.forEach(function(key, value) { - map.set(key, value); - }); else for (var key in object) map.set(key, object[key]); - return map; - }; - function d3_Map() {} - d3_class(d3_Map, { - has: function(key) { - return d3_map_prefix + key in this; - }, - get: function(key) { - return this[d3_map_prefix + key]; - }, - set: function(key, value) { - return this[d3_map_prefix + key] = value; - }, - remove: function(key) { - key = d3_map_prefix + key; - return key in this && delete this[key]; - }, - keys: function() { - var keys = []; - this.forEach(function(key) { - keys.push(key); - }); - return keys; - }, - values: function() { - var values = []; - this.forEach(function(key, value) { - values.push(value); - }); - return values; - }, - entries: function() { - var entries = []; - this.forEach(function(key, value) { - entries.push({ - key: key, - value: value - }); - }); - return entries; - }, - forEach: function(f) { - for (var key in this) { - if (key.charCodeAt(0) === d3_map_prefixCode) { - f.call(this, key.substring(1), this[key]); - } - } - } - }); - var d3_map_prefix = "\0", d3_map_prefixCode = d3_map_prefix.charCodeAt(0); - d3.nest = function() { - var nest = {}, keys = [], sortKeys = [], sortValues, rollup; - function map(mapType, array, depth) { - if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; - var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(object = array[i]))) { - values.push(object); - } else { - valuesByKey.set(keyValue, [ object ]); - } - } - if (mapType) { - object = mapType(); - setter = function(keyValue, values) { - object.set(keyValue, map(mapType, values, depth)); - }; - } else { - object = {}; - setter = function(keyValue, values) { - object[keyValue] = map(mapType, values, depth); - }; - } - valuesByKey.forEach(setter); - return object; - } - function entries(map, depth) { - if (depth >= keys.length) return map; - var array = [], sortKey = sortKeys[depth++]; - map.forEach(function(key, keyMap) { - array.push({ - key: key, - values: entries(keyMap, depth) - }); - }); - return sortKey ? array.sort(function(a, b) { - return sortKey(a.key, b.key); - }) : array; - } - nest.map = function(array, mapType) { - return map(mapType, array, 0); - }; - nest.entries = function(array) { - return entries(map(d3.map, array, 0), 0); - }; - nest.key = function(d) { - keys.push(d); - return nest; - }; - nest.sortKeys = function(order) { - sortKeys[keys.length - 1] = order; - return nest; - }; - nest.sortValues = function(order) { - sortValues = order; - return nest; - }; - nest.rollup = function(f) { - rollup = f; - return nest; - }; - return nest; - }; - d3.set = function(array) { - var set = new d3_Set(); - if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); - return set; - }; - function d3_Set() {} - d3_class(d3_Set, { - has: function(value) { - return d3_map_prefix + value in this; - }, - add: function(value) { - this[d3_map_prefix + value] = true; - return value; - }, - remove: function(value) { - value = d3_map_prefix + value; - return value in this && delete this[value]; - }, - values: function() { - var values = []; - this.forEach(function(value) { - values.push(value); - }); - return values; - }, - forEach: function(f) { - for (var value in this) { - if (value.charCodeAt(0) === d3_map_prefixCode) { - f.call(this, value.substring(1)); - } - } - } - }); - d3.behavior = {}; - d3.rebind = function(target, source) { - var i = 1, n = arguments.length, method; - while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); - return target; - }; - function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return value === source ? target : value; - }; - } - function d3_vendorSymbol(object, name) { - if (name in object) return name; - name = name.charAt(0).toUpperCase() + name.substring(1); - for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { - var prefixName = d3_vendorPrefixes[i] + name; - if (prefixName in object) return prefixName; - } - } - var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; - function d3_noop() {} - d3.dispatch = function() { - var dispatch = new d3_dispatch(), i = -1, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - return dispatch; - }; - function d3_dispatch() {} - d3_dispatch.prototype.on = function(type, listener) { - var i = type.indexOf("."), name = ""; - if (i >= 0) { - name = type.substring(i + 1); - type = type.substring(0, i); - } - if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); - if (arguments.length === 2) { - if (listener == null) for (type in this) { - if (this.hasOwnProperty(type)) this[type].on(name, null); - } - return this; - } - }; - function d3_dispatch_event(dispatch) { - var listeners = [], listenerByName = new d3_Map(); - function event() { - var z = listeners, i = -1, n = z.length, l; - while (++i < n) if (l = z[i].on) l.apply(this, arguments); - return dispatch; - } - event.on = function(name, listener) { - var l = listenerByName.get(name), i; - if (arguments.length < 2) return l && l.on; - if (l) { - l.on = null; - listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); - listenerByName.remove(name); - } - if (listener) listeners.push(listenerByName.set(name, { - on: listener - })); - return dispatch; - }; - return event; - } - d3.event = null; - function d3_eventPreventDefault() { - d3.event.preventDefault(); - } - function d3_eventSource() { - var e = d3.event, s; - while (s = e.sourceEvent) e = s; - return e; - } - function d3_eventDispatch(target) { - var dispatch = new d3_dispatch(), i = 0, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - dispatch.of = function(thiz, argumentz) { - return function(e1) { - try { - var e0 = e1.sourceEvent = d3.event; - e1.target = target; - d3.event = e1; - dispatch[e1.type].apply(thiz, argumentz); - } finally { - d3.event = e0; - } - }; - }; - return dispatch; - } - d3.requote = function(s) { - return s.replace(d3_requote_re, "\\$&"); - }; - var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; - var d3_subclass = {}.__proto__ ? function(object, prototype) { - object.__proto__ = prototype; - } : function(object, prototype) { - for (var property in prototype) object[property] = prototype[property]; - }; - function d3_selection(groups) { - d3_subclass(groups, d3_selectionPrototype); - return groups; - } - var d3_select = function(s, n) { - return n.querySelector(s); - }, d3_selectAll = function(s, n) { - return n.querySelectorAll(s); - }, d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) { - return d3_selectMatcher.call(n, s); - }; - if (typeof Sizzle === "function") { - d3_select = function(s, n) { - return Sizzle(s, n)[0] || null; - }; - d3_selectAll = function(s, n) { - return Sizzle.uniqueSort(Sizzle(s, n)); - }; - d3_selectMatches = Sizzle.matchesSelector; - } - d3.selection = function() { - return d3_selectionRoot; - }; - var d3_selectionPrototype = d3.selection.prototype = []; - d3_selectionPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, group, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(subnode = selector.call(node, node.__data__, i, j)); - if (subnode && "__data__" in node) subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selector(selector) { - return typeof selector === "function" ? selector : function() { - return d3_select(selector, this); - }; - } - d3_selectionPrototype.selectAll = function(selector) { - var subgroups = [], subgroup, node; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); - subgroup.parentNode = node; - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selectorAll(selector) { - return typeof selector === "function" ? selector : function() { - return d3_selectAll(selector, this); - }; - } - var d3_nsPrefix = { - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" - }; - d3.ns = { - prefix: d3_nsPrefix, - qualify: function(name) { - var i = name.indexOf(":"), prefix = name; - if (i >= 0) { - prefix = name.substring(0, i); - name = name.substring(i + 1); - } - return d3_nsPrefix.hasOwnProperty(prefix) ? { - space: d3_nsPrefix[prefix], - local: name - } : name; - } - }; - d3_selectionPrototype.attr = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(); - name = d3.ns.qualify(name); - return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); - } - for (value in name) this.each(d3_selection_attr(value, name[value])); - return this; - } - return this.each(d3_selection_attr(name, value)); - }; - function d3_selection_attr(name, value) { - name = d3.ns.qualify(name); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrConstant() { - this.setAttribute(name, value); - } - function attrConstantNS() { - this.setAttributeNS(name.space, name.local, value); - } - function attrFunction() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); - } - function attrFunctionNS() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); - } - return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; - } - function d3_collapse(s) { - return s.trim().replace(/\s+/g, " "); - } - d3_selectionPrototype.classed = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(), n = (name = name.trim().split(/^|\s+/g)).length, i = -1; - if (value = node.classList) { - while (++i < n) if (!value.contains(name[i])) return false; - } else { - value = node.getAttribute("class"); - while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; - } - return true; - } - for (value in name) this.each(d3_selection_classed(value, name[value])); - return this; - } - return this.each(d3_selection_classed(name, value)); - }; - function d3_selection_classedRe(name) { - return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); - } - function d3_selection_classed(name, value) { - name = name.trim().split(/\s+/).map(d3_selection_classedName); - var n = name.length; - function classedConstant() { - var i = -1; - while (++i < n) name[i](this, value); - } - function classedFunction() { - var i = -1, x = value.apply(this, arguments); - while (++i < n) name[i](this, x); - } - return typeof value === "function" ? classedFunction : classedConstant; - } - function d3_selection_classedName(name) { - var re = d3_selection_classedRe(name); - return function(node, value) { - if (c = node.classList) return value ? c.add(name) : c.remove(name); - var c = node.getAttribute("class") || ""; - if (value) { - re.lastIndex = 0; - if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); - } else { - node.setAttribute("class", d3_collapse(c.replace(re, " "))); - } - }; - } - d3_selectionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); - return this; - } - if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); - priority = ""; - } - return this.each(d3_selection_style(name, value, priority)); - }; - function d3_selection_style(name, value, priority) { - function styleNull() { - this.style.removeProperty(name); - } - function styleConstant() { - this.style.setProperty(name, value, priority); - } - function styleFunction() { - var x = value.apply(this, arguments); - if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); - } - return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; - } - d3_selectionPrototype.property = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") return this.node()[name]; - for (value in name) this.each(d3_selection_property(value, name[value])); - return this; - } - return this.each(d3_selection_property(name, value)); - }; - function d3_selection_property(name, value) { - function propertyNull() { - delete this[name]; - } - function propertyConstant() { - this[name] = value; - } - function propertyFunction() { - var x = value.apply(this, arguments); - if (x == null) delete this[name]; else this[name] = x; - } - return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; - } - d3_selectionPrototype.text = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - } : value == null ? function() { - this.textContent = ""; - } : function() { - this.textContent = value; - }) : this.node().textContent; - }; - d3_selectionPrototype.html = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - } : value == null ? function() { - this.innerHTML = ""; - } : function() { - this.innerHTML = value; - }) : this.node().innerHTML; - }; - d3_selectionPrototype.append = function(name) { - name = d3_selection_creator(name); - return this.select(function() { - return this.appendChild(name.apply(this, arguments)); - }); - }; - function d3_selection_creator(name) { - return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() { - return d3_document.createElementNS(name.space, name.local); - } : function() { - return d3_document.createElementNS(this.namespaceURI, name); - }; - } - d3_selectionPrototype.insert = function(name, before) { - name = d3_selection_creator(name); - before = d3_selection_selector(before); - return this.select(function() { - return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments)); - }); - }; - d3_selectionPrototype.remove = function() { - return this.each(function() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - }); - }; - d3_selectionPrototype.data = function(value, key) { - var i = -1, n = this.length, group, node; - if (!arguments.length) { - value = new Array(n = (group = this[0]).length); - while (++i < n) { - if (node = group[i]) { - value[i] = node.__data__; - } - } - return value; - } - function bind(group, groupData) { - var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; - if (key) { - var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue; - for (i = -1; ++i < n; ) { - keyValue = key.call(node = group[i], node.__data__, i); - if (nodeByKeyValue.has(keyValue)) { - exitNodes[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - keyValues.push(keyValue); - } - for (i = -1; ++i < m; ) { - keyValue = key.call(groupData, nodeData = groupData[i], i); - if (node = nodeByKeyValue.get(keyValue)) { - updateNodes[i] = node; - node.__data__ = nodeData; - } else if (!dataByKeyValue.has(keyValue)) { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - dataByKeyValue.set(keyValue, nodeData); - nodeByKeyValue.remove(keyValue); - } - for (i = -1; ++i < n; ) { - if (nodeByKeyValue.has(keyValues[i])) { - exitNodes[i] = group[i]; - } - } - } else { - for (i = -1; ++i < n0; ) { - node = group[i]; - nodeData = groupData[i]; - if (node) { - node.__data__ = nodeData; - updateNodes[i] = node; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - } - for (;i < m; ++i) { - enterNodes[i] = d3_selection_dataNode(groupData[i]); - } - for (;i < n; ++i) { - exitNodes[i] = group[i]; - } - } - enterNodes.update = updateNodes; - enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; - enter.push(enterNodes); - update.push(updateNodes); - exit.push(exitNodes); - } - var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); - if (typeof value === "function") { - while (++i < n) { - bind(group = this[i], value.call(group, group.parentNode.__data__, i)); - } - } else { - while (++i < n) { - bind(group = this[i], value); - } - } - update.enter = function() { - return enter; - }; - update.exit = function() { - return exit; - }; - return update; - }; - function d3_selection_dataNode(data) { - return { - __data__: data - }; - } - d3_selectionPrototype.datum = function(value) { - return arguments.length ? this.property("__data__", value) : this.property("__data__"); - }; - d3_selectionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i)) { - subgroup.push(node); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_filter(selector) { - return function() { - return d3_selectMatches(this, selector); - }; - } - d3_selectionPrototype.order = function() { - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - return this; - }; - d3_selectionPrototype.sort = function(comparator) { - comparator = d3_selection_sortComparator.apply(this, arguments); - for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); - return this.order(); - }; - function d3_selection_sortComparator(comparator) { - if (!arguments.length) comparator = d3.ascending; - return function(a, b) { - return a && b ? comparator(a.__data__, b.__data__) : !a - !b; - }; - } - d3_selectionPrototype.each = function(callback) { - return d3_selection_each(this, function(node, i, j) { - callback.call(node, node.__data__, i, j); - }); - }; - function d3_selection_each(groups, callback) { - for (var j = 0, m = groups.length; j < m; j++) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { - if (node = group[i]) callback(node, i, j); - } - } - return groups; - } - d3_selectionPrototype.call = function(callback) { - var args = d3_array(arguments); - callback.apply(args[0] = this, args); - return this; - }; - d3_selectionPrototype.empty = function() { - return !this.node(); - }; - d3_selectionPrototype.node = function() { - for (var j = 0, m = this.length; j < m; j++) { - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - var node = group[i]; - if (node) return node; - } - } - return null; - }; - d3_selectionPrototype.size = function() { - var n = 0; - this.each(function() { - ++n; - }); - return n; - }; - function d3_selection_enter(selection) { - d3_subclass(selection, d3_selection_enterPrototype); - return selection; - } - var d3_selection_enterPrototype = []; - d3.selection.enter = d3_selection_enter; - d3.selection.enter.prototype = d3_selection_enterPrototype; - d3_selection_enterPrototype.append = d3_selectionPrototype.append; - d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; - d3_selection_enterPrototype.node = d3_selectionPrototype.node; - d3_selection_enterPrototype.call = d3_selectionPrototype.call; - d3_selection_enterPrototype.size = d3_selectionPrototype.size; - d3_selection_enterPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, upgroup, group, node; - for (var j = -1, m = this.length; ++j < m; ) { - upgroup = (group = this[j]).update; - subgroups.push(subgroup = []); - subgroup.parentNode = group.parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); - subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - d3_selection_enterPrototype.insert = function(name, before) { - if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); - return d3_selectionPrototype.insert.call(this, name, before); - }; - function d3_selection_enterInsertBefore(enter) { - var i0, j0; - return function(d, i, j) { - var group = enter[j].update, n = group.length, node; - if (j != j0) j0 = j, i0 = 0; - if (i >= i0) i0 = i + 1; - while (!(node = group[i0]) && ++i0 < n) ; - return node; - }; - } - d3_selectionPrototype.transition = function() { - var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || { - time: Date.now(), - ease: d3_ease_cubicInOut, - delay: 0, - duration: 250 - }; - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) d3_transitionNode(node, i, id, transition); - subgroup.push(node); - } - } - return d3_transition(subgroups, id); - }; - d3_selectionPrototype.interrupt = function() { - return this.each(d3_selection_interrupt); - }; - function d3_selection_interrupt() { - var lock = this.__transition__; - if (lock) ++lock.active; - } - d3.select = function(node) { - var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ]; - group.parentNode = d3_documentElement; - return d3_selection([ group ]); - }; - d3.selectAll = function(nodes) { - var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); - group.parentNode = d3_documentElement; - return d3_selection([ group ]); - }; - var d3_selectionRoot = d3.select(d3_documentElement); - d3_selectionPrototype.on = function(type, listener, capture) { - var n = arguments.length; - if (n < 3) { - if (typeof type !== "string") { - if (n < 2) listener = false; - for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); - return this; - } - if (n < 2) return (n = this.node()["__on" + type]) && n._; - capture = false; - } - return this.each(d3_selection_on(type, listener, capture)); - }; - function d3_selection_on(type, listener, capture) { - var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; - if (i > 0) type = type.substring(0, i); - var filter = d3_selection_onFilters.get(type); - if (filter) type = filter, wrap = d3_selection_onFilter; - function onRemove() { - var l = this[name]; - if (l) { - this.removeEventListener(type, l, l.$); - delete this[name]; - } - } - function onAdd() { - var l = wrap(listener, d3_array(arguments)); - onRemove.call(this); - this.addEventListener(type, this[name] = l, l.$ = capture); - l._ = listener; - } - function removeAll() { - var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; - for (var name in this) { - if (match = name.match(re)) { - var l = this[name]; - this.removeEventListener(match[1], l, l.$); - delete this[name]; - } - } - } - return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; - } - var d3_selection_onFilters = d3.map({ - mouseenter: "mouseover", - mouseleave: "mouseout" - }); - d3_selection_onFilters.forEach(function(k) { - if ("on" + k in d3_document) d3_selection_onFilters.remove(k); - }); - function d3_selection_onListener(listener, argumentz) { - return function(e) { - var o = d3.event; - d3.event = e; - argumentz[0] = this.__data__; - try { - listener.apply(this, argumentz); - } finally { - d3.event = o; - } - }; - } - function d3_selection_onFilter(listener, argumentz) { - var l = d3_selection_onListener(listener, argumentz); - return function(e) { - var target = this, related = e.relatedTarget; - if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { - l.call(target, e); - } - }; - } - var d3_event_dragSelect = d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0; - function d3_event_dragSuppress() { - var name = ".dragsuppress-" + ++d3_event_dragId, touchmove = "touchmove" + name, selectstart = "selectstart" + name, dragstart = "dragstart" + name, click = "click" + name, w = d3.select(d3_window).on(touchmove, d3_eventPreventDefault).on(selectstart, d3_eventPreventDefault).on(dragstart, d3_eventPreventDefault), style = d3_documentElement.style, select = style[d3_event_dragSelect]; - style[d3_event_dragSelect] = "none"; - return function(suppressClick) { - w.on(name, null); - style[d3_event_dragSelect] = select; - if (suppressClick) { - function off() { - w.on(click, null); - } - w.on(click, function() { - d3_eventPreventDefault(); - off(); - }, true); - setTimeout(off, 0); - } - }; - } - d3.mouse = function(container) { - return d3_mousePoint(container, d3_eventSource()); - }; - var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0; - function d3_mousePoint(container, e) { - if (e.changedTouches) e = e.changedTouches[0]; - var svg = container.ownerSVGElement || container; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) { - svg = d3.select("body").append("svg").style({ - position: "absolute", - top: 0, - left: 0, - margin: 0, - padding: 0, - border: "none" - }, "important"); - var ctm = svg[0][0].getScreenCTM(); - d3_mouse_bug44083 = !(ctm.f || ctm.e); - svg.remove(); - } - if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, - point.y = e.clientY; - point = point.matrixTransform(container.getScreenCTM().inverse()); - return [ point.x, point.y ]; - } - var rect = container.getBoundingClientRect(); - return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; - } - d3.touches = function(container, touches) { - if (arguments.length < 2) touches = d3_eventSource().touches; - return touches ? d3_array(touches).map(function(touch) { - var point = d3_mousePoint(container, touch); - point.identifier = touch.identifier; - return point; - }) : []; - }; - d3.behavior.drag = function() { - var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, "mousemove", "mouseup"), touchstart = dragstart(touchid, touchposition, "touchmove", "touchend"); - function drag() { - this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); - } - function touchid() { - return d3.event.changedTouches[0].identifier; - } - function touchposition(parent, id) { - return d3.touches(parent).filter(function(p) { - return p.identifier === id; - })[0]; - } - function dragstart(id, position, move, end) { - return function() { - var target = this, parent = target.parentNode, event_ = event.of(target, arguments), eventTarget = d3.event.target, eventId = id(), drag = eventId == null ? "drag" : "drag-" + eventId, origin_ = position(parent, eventId), dragged = 0, offset, w = d3.select(d3_window).on(move + "." + drag, moved).on(end + "." + drag, ended), dragRestore = d3_event_dragSuppress(); - if (origin) { - offset = origin.apply(target, arguments); - offset = [ offset.x - origin_[0], offset.y - origin_[1] ]; - } else { - offset = [ 0, 0 ]; - } - event_({ - type: "dragstart" - }); - function moved() { - var p = position(parent, eventId), dx = p[0] - origin_[0], dy = p[1] - origin_[1]; - dragged |= dx | dy; - origin_ = p; - event_({ - type: "drag", - x: p[0] + offset[0], - y: p[1] + offset[1], - dx: dx, - dy: dy - }); - } - function ended() { - w.on(move + "." + drag, null).on(end + "." + drag, null); - dragRestore(dragged && d3.event.target === eventTarget); - event_({ - type: "dragend" - }); - } - }; - } - drag.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return drag; - }; - return d3.rebind(drag, event, "on"); - }; - var π = Math.PI, ε = 1e-6, ε2 = ε * ε, d3_radians = π / 180, d3_degrees = 180 / π; - function d3_sgn(x) { - return x > 0 ? 1 : x < 0 ? -1 : 0; - } - function d3_acos(x) { - return x > 1 ? 0 : x < -1 ? π : Math.acos(x); - } - function d3_asin(x) { - return x > 1 ? π / 2 : x < -1 ? -π / 2 : Math.asin(x); - } - function d3_sinh(x) { - return (Math.exp(x) - Math.exp(-x)) / 2; - } - function d3_cosh(x) { - return (Math.exp(x) + Math.exp(-x)) / 2; - } - function d3_tanh(x) { - return d3_sinh(x) / d3_cosh(x); - } - function d3_haversin(x) { - return (x = Math.sin(x / 2)) * x; - } - var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4; - d3.interpolateZoom = function(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; - var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ; - function interpolate(t) { - var s = t * S; - if (dr) { - var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); - return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ]; - } - return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ]; - } - interpolate.duration = S * 1e3; - return interpolate; - }; - d3.behavior.zoom = function() { - var view = { - x: 0, - y: 0, - k: 1 - }, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; - function zoom(g) { - g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); - } - zoom.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), view1 = view; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.zoom", function() { - view = this.__chart__ || { - x: 0, - y: 0, - k: 1 - }; - zoomstarted(event_); - }).tween("zoom:zoom", function() { - var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); - return function(t) { - var l = i(t), k = dx / l[2]; - this.__chart__ = view = { - x: cx - l[0] * k, - y: cy - l[1] * k, - k: k - }; - zoomed(event_); - }; - }).each("end.zoom", function() { - zoomended(event_); - }); - } else { - this.__chart__ = view; - zoomstarted(event_); - zoomed(event_); - zoomended(event_); - } - }); - }; - zoom.translate = function(_) { - if (!arguments.length) return [ view.x, view.y ]; - view = { - x: +_[0], - y: +_[1], - k: view.k - }; - rescale(); - return zoom; - }; - zoom.scale = function(_) { - if (!arguments.length) return view.k; - view = { - x: view.x, - y: view.y, - k: +_ - }; - rescale(); - return zoom; - }; - zoom.scaleExtent = function(_) { - if (!arguments.length) return scaleExtent; - scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; - return zoom; - }; - zoom.center = function(_) { - if (!arguments.length) return center; - center = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.size = function(_) { - if (!arguments.length) return size; - size = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.x = function(z) { - if (!arguments.length) return x1; - x1 = z; - x0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - zoom.y = function(z) { - if (!arguments.length) return y1; - y1 = z; - y0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - function location(p) { - return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; - } - function point(l) { - return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; - } - function scaleTo(s) { - view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); - } - function translateTo(p, l) { - l = point(l); - view.x += p[0] - l[0]; - view.y += p[1] - l[1]; - } - function rescale() { - if (x1) x1.domain(x0.range().map(function(x) { - return (x - view.x) / view.k; - }).map(x0.invert)); - if (y1) y1.domain(y0.range().map(function(y) { - return (y - view.y) / view.k; - }).map(y0.invert)); - } - function zoomstarted(event) { - event({ - type: "zoomstart" - }); - } - function zoomed(event) { - rescale(); - event({ - type: "zoom", - scale: view.k, - translate: [ view.x, view.y ] - }); - } - function zoomended(event) { - event({ - type: "zoomend" - }); - } - function mousedowned() { - var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, dragged = 0, w = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), l = location(d3.mouse(target)), dragRestore = d3_event_dragSuppress(); - d3_selection_interrupt.call(target); - zoomstarted(event_); - function moved() { - dragged = 1; - translateTo(d3.mouse(target), l); - zoomed(event_); - } - function ended() { - w.on(mousemove, d3_window === target ? mousewheelreset : null).on(mouseup, null); - dragRestore(dragged && d3.event.target === eventTarget); - zoomended(event_); - } - } - function touchstarted() { - var target = this, event_ = event.of(target, arguments), locations0 = {}, distance0 = 0, scale0, eventId = d3.event.changedTouches[0].identifier, touchmove = "touchmove.zoom-" + eventId, touchend = "touchend.zoom-" + eventId, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress(); - d3_selection_interrupt.call(target); - started(); - zoomstarted(event_); - function relocate() { - var touches = d3.touches(target); - scale0 = view.k; - touches.forEach(function(t) { - if (t.identifier in locations0) locations0[t.identifier] = location(t); - }); - return touches; - } - function started() { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - locations0[changed[i].identifier] = null; - } - var touches = relocate(), now = Date.now(); - if (touches.length === 1) { - if (now - touchtime < 500) { - var p = touches[0], l = locations0[p.identifier]; - scaleTo(view.k * 2); - translateTo(p, l); - d3_eventPreventDefault(); - zoomed(event_); - } - touchtime = now; - } else if (touches.length > 1) { - var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; - distance0 = dx * dx + dy * dy; - } - } - function moved() { - var touches = d3.touches(target), p0, l0, p1, l1; - for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { - p1 = touches[i]; - if (l1 = locations0[p1.identifier]) { - if (l0) break; - p0 = p1, l0 = l1; - } - } - if (l1) { - var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); - p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; - l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; - scaleTo(scale1 * scale0); - } - touchtime = null; - translateTo(p0, l0); - zoomed(event_); - } - function ended() { - if (d3.event.touches.length) { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - delete locations0[changed[i].identifier]; - } - for (var identifier in locations0) { - return void relocate(); - } - } - w.on(touchmove, null).on(touchend, null); - t.on(mousedown, mousedowned).on(touchstart, touchstarted); - dragRestore(); - zoomended(event_); - } - } - function mousewheeled() { - var event_ = event.of(this, arguments); - if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), - zoomstarted(event_); - mousewheelTimer = setTimeout(function() { - mousewheelTimer = null; - zoomended(event_); - }, 50); - d3_eventPreventDefault(); - var point = center || d3.mouse(this); - if (!translate0) translate0 = location(point); - scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); - translateTo(point, translate0); - zoomed(event_); - } - function mousewheelreset() { - translate0 = null; - } - function dblclicked() { - var event_ = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2; - zoomstarted(event_); - scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); - translateTo(p, l); - zoomed(event_); - zoomended(event_); - } - return d3.rebind(zoom, event, "on"); - }; - var d3_behavior_zoomInfinity = [ 0, Infinity ]; - var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); - }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return d3.event.wheelDelta; - }, "mousewheel") : (d3_behavior_zoomDelta = function() { - return -d3.event.detail; - }, "MozMousePixelScroll"); - function d3_Color() {} - d3_Color.prototype.toString = function() { - return this.rgb() + ""; - }; - d3.hsl = function(h, s, l) { - return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l); - }; - function d3_hsl(h, s, l) { - return new d3_Hsl(h, s, l); - } - function d3_Hsl(h, s, l) { - this.h = h; - this.s = s; - this.l = l; - } - var d3_hslPrototype = d3_Hsl.prototype = new d3_Color(); - d3_hslPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, this.l / k); - }; - d3_hslPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, k * this.l); - }; - d3_hslPrototype.rgb = function() { - return d3_hsl_rgb(this.h, this.s, this.l); - }; - function d3_hsl_rgb(h, s, l) { - var m1, m2; - h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; - s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; - l = l < 0 ? 0 : l > 1 ? 1 : l; - m2 = l <= .5 ? l * (1 + s) : l + s - l * s; - m1 = 2 * l - m2; - function v(h) { - if (h > 360) h -= 360; else if (h < 0) h += 360; - if (h < 60) return m1 + (m2 - m1) * h / 60; - if (h < 180) return m2; - if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; - return m1; - } - function vv(h) { - return Math.round(v(h) * 255); - } - return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); - } - d3.hcl = function(h, c, l) { - return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l); - }; - function d3_hcl(h, c, l) { - return new d3_Hcl(h, c, l); - } - function d3_Hcl(h, c, l) { - this.h = h; - this.c = c; - this.l = l; - } - var d3_hclPrototype = d3_Hcl.prototype = new d3_Color(); - d3_hclPrototype.brighter = function(k) { - return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.darker = function(k) { - return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.rgb = function() { - return d3_hcl_lab(this.h, this.c, this.l).rgb(); - }; - function d3_hcl_lab(h, c, l) { - if (isNaN(h)) h = 0; - if (isNaN(c)) c = 0; - return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); - } - d3.lab = function(l, a, b) { - return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b); - }; - function d3_lab(l, a, b) { - return new d3_Lab(l, a, b); - } - function d3_Lab(l, a, b) { - this.l = l; - this.a = a; - this.b = b; - } - var d3_lab_K = 18; - var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; - var d3_labPrototype = d3_Lab.prototype = new d3_Color(); - d3_labPrototype.brighter = function(k) { - return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.darker = function(k) { - return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.rgb = function() { - return d3_lab_rgb(this.l, this.a, this.b); - }; - function d3_lab_rgb(l, a, b) { - var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; - x = d3_lab_xyz(x) * d3_lab_X; - y = d3_lab_xyz(y) * d3_lab_Y; - z = d3_lab_xyz(z) * d3_lab_Z; - return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); - } - function d3_lab_hcl(l, a, b) { - return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l); - } - function d3_lab_xyz(x) { - return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; - } - function d3_xyz_lab(x) { - return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; - } - function d3_xyz_rgb(r) { - return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); - } - d3.rgb = function(r, g, b) { - return arguments.length === 1 ? r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : d3_rgb(~~r, ~~g, ~~b); - }; - function d3_rgbNumber(value) { - return d3_rgb(value >> 16, value >> 8 & 255, value & 255); - } - function d3_rgbString(value) { - return d3_rgbNumber(value) + ""; - } - function d3_rgb(r, g, b) { - return new d3_Rgb(r, g, b); - } - function d3_Rgb(r, g, b) { - this.r = r; - this.g = g; - this.b = b; - } - var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color(); - d3_rgbPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - var r = this.r, g = this.g, b = this.b, i = 30; - if (!r && !g && !b) return d3_rgb(i, i, i); - if (r && r < i) r = i; - if (g && g < i) g = i; - if (b && b < i) b = i; - return d3_rgb(Math.min(255, ~~(r / k)), Math.min(255, ~~(g / k)), Math.min(255, ~~(b / k))); - }; - d3_rgbPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_rgb(~~(k * this.r), ~~(k * this.g), ~~(k * this.b)); - }; - d3_rgbPrototype.hsl = function() { - return d3_rgb_hsl(this.r, this.g, this.b); - }; - d3_rgbPrototype.toString = function() { - return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); - }; - function d3_rgb_hex(v) { - return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); - } - function d3_rgb_parse(format, rgb, hsl) { - var r = 0, g = 0, b = 0, m1, m2, name; - m1 = /([a-z]+)\((.*)\)/i.exec(format); - if (m1) { - m2 = m1[2].split(","); - switch (m1[1]) { - case "hsl": - { - return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); - } - - case "rgb": - { - return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); - } - } - } - if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b); - if (format != null && format.charAt(0) === "#") { - if (format.length === 4) { - r = format.charAt(1); - r += r; - g = format.charAt(2); - g += g; - b = format.charAt(3); - b += b; - } else if (format.length === 7) { - r = format.substring(1, 3); - g = format.substring(3, 5); - b = format.substring(5, 7); - } - r = parseInt(r, 16); - g = parseInt(g, 16); - b = parseInt(b, 16); - } - return rgb(r, g, b); - } - function d3_rgb_hsl(r, g, b) { - var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; - if (d) { - s = l < .5 ? d / (max + min) : d / (2 - max - min); - if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; - h *= 60; - } else { - h = NaN; - s = l > 0 && l < 1 ? 0 : h; - } - return d3_hsl(h, s, l); - } - function d3_rgb_lab(r, g, b) { - r = d3_rgb_xyz(r); - g = d3_rgb_xyz(g); - b = d3_rgb_xyz(b); - var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); - return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); - } - function d3_rgb_xyz(r) { - return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); - } - function d3_rgb_parseNumber(c) { - var f = parseFloat(c); - return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; - } - var d3_rgb_names = d3.map({ - aliceblue: 15792383, - antiquewhite: 16444375, - aqua: 65535, - aquamarine: 8388564, - azure: 15794175, - beige: 16119260, - bisque: 16770244, - black: 0, - blanchedalmond: 16772045, - blue: 255, - blueviolet: 9055202, - brown: 10824234, - burlywood: 14596231, - cadetblue: 6266528, - chartreuse: 8388352, - chocolate: 13789470, - coral: 16744272, - cornflowerblue: 6591981, - cornsilk: 16775388, - crimson: 14423100, - cyan: 65535, - darkblue: 139, - darkcyan: 35723, - darkgoldenrod: 12092939, - darkgray: 11119017, - darkgreen: 25600, - darkgrey: 11119017, - darkkhaki: 12433259, - darkmagenta: 9109643, - darkolivegreen: 5597999, - darkorange: 16747520, - darkorchid: 10040012, - darkred: 9109504, - darksalmon: 15308410, - darkseagreen: 9419919, - darkslateblue: 4734347, - darkslategray: 3100495, - darkslategrey: 3100495, - darkturquoise: 52945, - darkviolet: 9699539, - deeppink: 16716947, - deepskyblue: 49151, - dimgray: 6908265, - dimgrey: 6908265, - dodgerblue: 2003199, - firebrick: 11674146, - floralwhite: 16775920, - forestgreen: 2263842, - fuchsia: 16711935, - gainsboro: 14474460, - ghostwhite: 16316671, - gold: 16766720, - goldenrod: 14329120, - gray: 8421504, - green: 32768, - greenyellow: 11403055, - grey: 8421504, - honeydew: 15794160, - hotpink: 16738740, - indianred: 13458524, - indigo: 4915330, - ivory: 16777200, - khaki: 15787660, - lavender: 15132410, - lavenderblush: 16773365, - lawngreen: 8190976, - lemonchiffon: 16775885, - lightblue: 11393254, - lightcoral: 15761536, - lightcyan: 14745599, - lightgoldenrodyellow: 16448210, - lightgray: 13882323, - lightgreen: 9498256, - lightgrey: 13882323, - lightpink: 16758465, - lightsalmon: 16752762, - lightseagreen: 2142890, - lightskyblue: 8900346, - lightslategray: 7833753, - lightslategrey: 7833753, - lightsteelblue: 11584734, - lightyellow: 16777184, - lime: 65280, - limegreen: 3329330, - linen: 16445670, - magenta: 16711935, - maroon: 8388608, - mediumaquamarine: 6737322, - mediumblue: 205, - mediumorchid: 12211667, - mediumpurple: 9662683, - mediumseagreen: 3978097, - mediumslateblue: 8087790, - mediumspringgreen: 64154, - mediumturquoise: 4772300, - mediumvioletred: 13047173, - midnightblue: 1644912, - mintcream: 16121850, - mistyrose: 16770273, - moccasin: 16770229, - navajowhite: 16768685, - navy: 128, - oldlace: 16643558, - olive: 8421376, - olivedrab: 7048739, - orange: 16753920, - orangered: 16729344, - orchid: 14315734, - palegoldenrod: 15657130, - palegreen: 10025880, - paleturquoise: 11529966, - palevioletred: 14381203, - papayawhip: 16773077, - peachpuff: 16767673, - peru: 13468991, - pink: 16761035, - plum: 14524637, - powderblue: 11591910, - purple: 8388736, - red: 16711680, - rosybrown: 12357519, - royalblue: 4286945, - saddlebrown: 9127187, - salmon: 16416882, - sandybrown: 16032864, - seagreen: 3050327, - seashell: 16774638, - sienna: 10506797, - silver: 12632256, - skyblue: 8900331, - slateblue: 6970061, - slategray: 7372944, - slategrey: 7372944, - snow: 16775930, - springgreen: 65407, - steelblue: 4620980, - tan: 13808780, - teal: 32896, - thistle: 14204888, - tomato: 16737095, - turquoise: 4251856, - violet: 15631086, - wheat: 16113331, - white: 16777215, - whitesmoke: 16119285, - yellow: 16776960, - yellowgreen: 10145074 - }); - d3_rgb_names.forEach(function(key, value) { - d3_rgb_names.set(key, d3_rgbNumber(value)); - }); - function d3_functor(v) { - return typeof v === "function" ? v : function() { - return v; - }; - } - d3.functor = d3_functor; - function d3_identity(d) { - return d; - } - d3.xhr = d3_xhrType(d3_identity); - function d3_xhrType(response) { - return function(url, mimeType, callback) { - if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, - mimeType = null; - return d3_xhr(url, mimeType, response, callback); - }; - } - function d3_xhr(url, mimeType, response, callback) { - var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; - if (d3_window.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); - "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { - request.readyState > 3 && respond(); - }; - function respond() { - var status = request.status, result; - if (!status && request.responseText || status >= 200 && status < 300 || status === 304) { - try { - result = response.call(xhr, request); - } catch (e) { - dispatch.error.call(xhr, e); - return; - } - dispatch.load.call(xhr, result); - } else { - dispatch.error.call(xhr, request); - } - } - request.onprogress = function(event) { - var o = d3.event; - d3.event = event; - try { - dispatch.progress.call(xhr, request); - } finally { - d3.event = o; - } - }; - xhr.header = function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers[name]; - if (value == null) delete headers[name]; else headers[name] = value + ""; - return xhr; - }; - xhr.mimeType = function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return xhr; - }; - xhr.responseType = function(value) { - if (!arguments.length) return responseType; - responseType = value; - return xhr; - }; - xhr.response = function(value) { - response = value; - return xhr; - }; - [ "get", "post" ].forEach(function(method) { - xhr[method] = function() { - return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); - }; - }); - xhr.send = function(method, data, callback) { - if (arguments.length === 2 && typeof data === "function") callback = data, data = null; - request.open(method, url, true); - if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; - if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); - if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); - if (responseType != null) request.responseType = responseType; - if (callback != null) xhr.on("error", callback).on("load", function(request) { - callback(null, request); - }); - dispatch.beforesend.call(xhr, request); - request.send(data == null ? null : data); - return xhr; - }; - xhr.abort = function() { - request.abort(); - return xhr; - }; - d3.rebind(xhr, dispatch, "on"); - return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); - } - function d3_xhr_fixCallback(callback) { - return callback.length === 1 ? function(error, request) { - callback(error == null ? request : null); - } : callback; - } - d3.dsv = function(delimiter, mimeType) { - var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); - function dsv(url, row, callback) { - if (arguments.length < 3) callback = row, row = null; - var xhr = d3.xhr(url, mimeType, callback); - xhr.row = function(_) { - return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; - }; - return xhr.row(row); - } - function response(request) { - return dsv.parse(request.responseText); - } - function typedResponse(f) { - return function(request) { - return dsv.parse(request.responseText, f); - }; - } - dsv.parse = function(text, f) { - var o; - return dsv.parseRows(text, function(row, i) { - if (o) return o(row, i - 1); - var a = new Function("d", "return {" + row.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); - o = f ? function(row, i) { - return f(a(row), i); - } : a; - }); - }; - dsv.parseRows = function(text, f) { - var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; - function token() { - if (I >= N) return EOF; - if (eol) return eol = false, EOL; - var j = I; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - var c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.substring(j + 1, i).replace(/""/g, '"'); - } - while (I < N) { - var c = text.charCodeAt(I++), k = 1; - if (c === 10) eol = true; else if (c === 13) { - eol = true; - if (text.charCodeAt(I) === 10) ++I, ++k; - } else if (c !== delimiterCode) continue; - return text.substring(j, I - k); - } - return text.substring(j); - } - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && !(a = f(a, n++))) continue; - rows.push(a); - } - return rows; - }; - dsv.format = function(rows) { - if (Array.isArray(rows[0])) return dsv.formatRows(rows); - var fieldSet = new d3_Set(), fields = []; - rows.forEach(function(row) { - for (var field in row) { - if (!fieldSet.has(field)) { - fields.push(fieldSet.add(field)); - } - } - }); - return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { - return fields.map(function(field) { - return formatValue(row[field]); - }).join(delimiter); - })).join("\n"); - }; - dsv.formatRows = function(rows) { - return rows.map(formatRow).join("\n"); - }; - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - function formatValue(text) { - return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; - } - return dsv; - }; - d3.csv = d3.dsv(",", "text/csv"); - d3.tsv = d3.dsv(" ", "text/tab-separated-values"); - var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) { - setTimeout(callback, 17); - }; - d3.timer = function(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - var time = then + delay, timer = { - callback: callback, - time: time, - next: null - }; - if (d3_timer_queueTail) d3_timer_queueTail.next = timer; else d3_timer_queueHead = timer; - d3_timer_queueTail = timer; - if (!d3_timer_interval) { - d3_timer_timeout = clearTimeout(d3_timer_timeout); - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - }; - function d3_timer_step() { - var now = d3_timer_mark(), delay = d3_timer_sweep() - now; - if (delay > 24) { - if (isFinite(delay)) { - clearTimeout(d3_timer_timeout); - d3_timer_timeout = setTimeout(d3_timer_step, delay); - } - d3_timer_interval = 0; - } else { - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - } - d3.timer.flush = function() { - d3_timer_mark(); - d3_timer_sweep(); - }; - function d3_timer_replace(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - d3_timer_active.callback = callback; - d3_timer_active.time = then + delay; - } - function d3_timer_mark() { - var now = Date.now(); - d3_timer_active = d3_timer_queueHead; - while (d3_timer_active) { - if (now >= d3_timer_active.time) d3_timer_active.flush = d3_timer_active.callback(now - d3_timer_active.time); - d3_timer_active = d3_timer_active.next; - } - return now; - } - function d3_timer_sweep() { - var t0, t1 = d3_timer_queueHead, time = Infinity; - while (t1) { - if (t1.flush) { - t1 = t0 ? t0.next = t1.next : d3_timer_queueHead = t1.next; - } else { - if (t1.time < time) time = t1.time; - t1 = (t0 = t1).next; - } - } - d3_timer_queueTail = t0; - return time; - } - var d3_format_decimalPoint = ".", d3_format_thousandsSeparator = ",", d3_format_grouping = [ 3, 3 ], d3_format_currencySymbol = "$"; - var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); - d3.formatPrefix = function(value, precision) { - var i = 0; - if (value) { - if (value < 0) value *= -1; - if (precision) value = d3.round(value, d3_format_precision(value, precision)); - i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); - i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3)); - } - return d3_formatPrefixes[8 + i / 3]; - }; - function d3_formatPrefix(d, i) { - var k = Math.pow(10, Math.abs(8 - i) * 3); - return { - scale: i > 8 ? function(d) { - return d / k; - } : function(d) { - return d * k; - }, - symbol: d - }; - } - d3.round = function(x, n) { - return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); - }; - d3.format = function(specifier) { - var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, suffix = "", integer = false; - if (precision) precision = +precision.substring(1); - if (zfill || fill === "0" && align === "=") { - zfill = fill = "0"; - align = "="; - if (comma) width -= Math.floor((width - 1) / 4); - } - switch (type) { - case "n": - comma = true; - type = "g"; - break; - - case "%": - scale = 100; - suffix = "%"; - type = "f"; - break; - - case "p": - scale = 100; - suffix = "%"; - type = "r"; - break; - - case "b": - case "o": - case "x": - case "X": - if (symbol === "#") symbol = "0" + type.toLowerCase(); - - case "c": - case "d": - integer = true; - precision = 0; - break; - - case "s": - scale = -1; - type = "r"; - break; - } - if (symbol === "#") symbol = ""; else if (symbol === "$") symbol = d3_format_currencySymbol; - if (type == "r" && !precision) type = "g"; - if (precision != null) { - if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); - } - type = d3_format_types.get(type) || d3_format_typeDefault; - var zcomma = zfill && comma; - return function(value) { - if (integer && value % 1) return ""; - var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; - if (scale < 0) { - var prefix = d3.formatPrefix(value, precision); - value = prefix.scale(value); - suffix = prefix.symbol; - } else { - value *= scale; - } - value = type(value, precision); - var i = value.lastIndexOf("."), before = i < 0 ? value : value.substring(0, i), after = i < 0 ? "" : d3_format_decimalPoint + value.substring(i + 1); - if (!zfill && comma) before = d3_format_group(before); - var length = symbol.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; - if (zcomma) before = d3_format_group(padding + before); - negative += symbol; - value = before + after; - return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + suffix; - }; - }; - var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; - var d3_format_types = d3.map({ - b: function(x) { - return x.toString(2); - }, - c: function(x) { - return String.fromCharCode(x); - }, - o: function(x) { - return x.toString(8); - }, - x: function(x) { - return x.toString(16); - }, - X: function(x) { - return x.toString(16).toUpperCase(); - }, - g: function(x, p) { - return x.toPrecision(p); - }, - e: function(x, p) { - return x.toExponential(p); - }, - f: function(x, p) { - return x.toFixed(p); - }, - r: function(x, p) { - return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); - } - }); - function d3_format_precision(x, p) { - return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); - } - function d3_format_typeDefault(x) { - return x + ""; - } - var d3_format_group = d3_identity; - if (d3_format_grouping) { - var d3_format_groupingLength = d3_format_grouping.length; - d3_format_group = function(value) { - var i = value.length, t = [], j = 0, g = d3_format_grouping[0]; - while (i > 0 && g > 0) { - t.push(value.substring(i -= g, i + g)); - g = d3_format_grouping[j = (j + 1) % d3_format_groupingLength]; - } - return t.reverse().join(d3_format_thousandsSeparator); - }; - } - d3.geo = {}; - function d3_adder() {} - d3_adder.prototype = { - s: 0, - t: 0, - add: function(y) { - d3_adderSum(y, this.t, d3_adderTemp); - d3_adderSum(d3_adderTemp.s, this.s, this); - if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; - }, - reset: function() { - this.s = this.t = 0; - }, - valueOf: function() { - return this.s; - } - }; - var d3_adderTemp = new d3_adder(); - function d3_adderSum(a, b, o) { - var x = o.s = a + b, bv = x - a, av = x - bv; - o.t = a - av + (b - bv); - } - d3.geo.stream = function(object, listener) { - if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { - d3_geo_streamObjectType[object.type](object, listener); - } else { - d3_geo_streamGeometry(object, listener); - } - }; - function d3_geo_streamGeometry(geometry, listener) { - if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { - d3_geo_streamGeometryType[geometry.type](geometry, listener); - } - } - var d3_geo_streamObjectType = { - Feature: function(feature, listener) { - d3_geo_streamGeometry(feature.geometry, listener); - }, - FeatureCollection: function(object, listener) { - var features = object.features, i = -1, n = features.length; - while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); - } - }; - var d3_geo_streamGeometryType = { - Sphere: function(object, listener) { - listener.sphere(); - }, - Point: function(object, listener) { - object = object.coordinates; - listener.point(object[0], object[1], object[2]); - }, - MultiPoint: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); - }, - LineString: function(object, listener) { - d3_geo_streamLine(object.coordinates, listener, 0); - }, - MultiLineString: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); - }, - Polygon: function(object, listener) { - d3_geo_streamPolygon(object.coordinates, listener); - }, - MultiPolygon: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); - }, - GeometryCollection: function(object, listener) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) d3_geo_streamGeometry(geometries[i], listener); - } - }; - function d3_geo_streamLine(coordinates, listener, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - listener.lineStart(); - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); - listener.lineEnd(); - } - function d3_geo_streamPolygon(coordinates, listener) { - var i = -1, n = coordinates.length; - listener.polygonStart(); - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); - listener.polygonEnd(); - } - d3.geo.area = function(object) { - d3_geo_areaSum = 0; - d3.geo.stream(object, d3_geo_area); - return d3_geo_areaSum; - }; - var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); - var d3_geo_area = { - sphere: function() { - d3_geo_areaSum += 4 * π; - }, - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_areaRingSum.reset(); - d3_geo_area.lineStart = d3_geo_areaRingStart; - }, - polygonEnd: function() { - var area = 2 * d3_geo_areaRingSum; - d3_geo_areaSum += area < 0 ? 4 * π + area : area; - d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; - } - }; - function d3_geo_areaRingStart() { - var λ00, φ00, λ0, cosφ0, sinφ0; - d3_geo_area.point = function(λ, φ) { - d3_geo_area.point = nextPoint; - λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), - sinφ0 = Math.sin(φ); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - φ = φ * d3_radians / 2 + π / 4; - var dλ = λ - λ0, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(dλ), v = k * Math.sin(dλ); - d3_geo_areaRingSum.add(Math.atan2(v, u)); - λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; - } - d3_geo_area.lineEnd = function() { - nextPoint(λ00, φ00); - }; - } - function d3_geo_cartesian(spherical) { - var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); - return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; - } - function d3_geo_cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - } - function d3_geo_cartesianCross(a, b) { - return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; - } - function d3_geo_cartesianAdd(a, b) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - } - function d3_geo_cartesianScale(vector, k) { - return [ vector[0] * k, vector[1] * k, vector[2] * k ]; - } - function d3_geo_cartesianNormalize(d) { - var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l; - d[1] /= l; - d[2] /= l; - } - function d3_geo_spherical(cartesian) { - return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; - } - function d3_geo_sphericalEqual(a, b) { - return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε; - } - d3.geo.bounds = function() { - var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; - var bound = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - bound.point = ringPoint; - bound.lineStart = ringStart; - bound.lineEnd = ringEnd; - dλSum = 0; - d3_geo_area.polygonStart(); - }, - polygonEnd: function() { - d3_geo_area.polygonEnd(); - bound.point = point; - bound.lineStart = lineStart; - bound.lineEnd = lineEnd; - if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; - range[0] = λ0, range[1] = λ1; - } - }; - function point(λ, φ) { - ranges.push(range = [ λ0 = λ, λ1 = λ ]); - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - function linePoint(λ, φ) { - var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); - if (p0) { - var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); - d3_geo_cartesianNormalize(inflection); - inflection = d3_geo_spherical(inflection); - var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = Math.abs(dλ) > 180; - if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = inflection[1] * d3_degrees; - if (φi > φ1) φ1 = φi; - } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = -inflection[1] * d3_degrees; - if (φi < φ0) φ0 = φi; - } else { - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - if (antimeridian) { - if (λ < λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } else { - if (λ1 >= λ0) { - if (λ < λ0) λ0 = λ; - if (λ > λ1) λ1 = λ; - } else { - if (λ > λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } - } - } else { - point(λ, φ); - } - p0 = p, λ_ = λ; - } - function lineStart() { - bound.point = linePoint; - } - function lineEnd() { - range[0] = λ0, range[1] = λ1; - bound.point = point; - p0 = null; - } - function ringPoint(λ, φ) { - if (p0) { - var dλ = λ - λ_; - dλSum += Math.abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; - } else λ__ = λ, φ__ = φ; - d3_geo_area.point(λ, φ); - linePoint(λ, φ); - } - function ringStart() { - d3_geo_area.lineStart(); - } - function ringEnd() { - ringPoint(λ__, φ__); - d3_geo_area.lineEnd(); - if (Math.abs(dλSum) > ε) λ0 = -(λ1 = 180); - range[0] = λ0, range[1] = λ1; - p0 = null; - } - function angle(λ0, λ1) { - return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; - } - function compareRanges(a, b) { - return a[0] - b[0]; - } - function withinRange(x, range) { - return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; - } - return function(feature) { - φ1 = λ1 = -(λ0 = φ0 = Infinity); - ranges = []; - d3.geo.stream(feature, bound); - var n = ranges.length; - if (n) { - ranges.sort(compareRanges); - for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { - b = ranges[i]; - if (withinRange(b[0], a) || withinRange(b[1], a)) { - if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; - if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; - } else { - merged.push(a = b); - } - } - var best = -Infinity, dλ; - for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { - b = merged[i]; - if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; - } - } - ranges = range = null; - return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; - }; - }(); - d3.geo.centroid = function(object) { - d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, d3_geo_centroid); - var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; - if (m < ε2) { - x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; - if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; - m = x * x + y * y + z * z; - if (m < ε2) return [ NaN, NaN ]; - } - return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; - }; - var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; - var d3_geo_centroid = { - sphere: d3_noop, - point: d3_geo_centroidPoint, - lineStart: d3_geo_centroidLineStart, - lineEnd: d3_geo_centroidLineEnd, - polygonStart: function() { - d3_geo_centroid.lineStart = d3_geo_centroidRingStart; - }, - polygonEnd: function() { - d3_geo_centroid.lineStart = d3_geo_centroidLineStart; - } - }; - function d3_geo_centroidPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); - } - function d3_geo_centroidPointXYZ(x, y, z) { - ++d3_geo_centroidW0; - d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; - d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; - d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; - } - function d3_geo_centroidLineStart() { - var x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroid.point = nextPoint; - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_centroidLineEnd() { - d3_geo_centroid.point = d3_geo_centroidPoint; - } - function d3_geo_centroidRingStart() { - var λ00, φ00, x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ00 = λ, φ00 = φ; - d3_geo_centroid.point = nextPoint; - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - d3_geo_centroid.lineEnd = function() { - nextPoint(λ00, φ00); - d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; - d3_geo_centroid.point = d3_geo_centroidPoint; - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); - d3_geo_centroidX2 += v * cx; - d3_geo_centroidY2 += v * cy; - d3_geo_centroidZ2 += v * cz; - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_true() { - return true; - } - function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) { - var subject = [], clip = []; - segments.forEach(function(segment) { - if ((n = segment.length - 1) <= 0) return; - var n, p0 = segment[0], p1 = segment[n]; - if (d3_geo_sphericalEqual(p0, p1)) { - listener.lineStart(); - for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); - listener.lineEnd(); - return; - } - var a = { - point: p0, - points: segment, - other: null, - visited: false, - entry: true, - subject: true - }, b = { - point: p0, - points: [ p0 ], - other: a, - visited: false, - entry: false, - subject: false - }; - a.other = b; - subject.push(a); - clip.push(b); - a = { - point: p1, - points: [ p1 ], - other: null, - visited: false, - entry: false, - subject: true - }; - b = { - point: p1, - points: [ p1 ], - other: a, - visited: false, - entry: true, - subject: false - }; - a.other = b; - subject.push(a); - clip.push(b); - }); - clip.sort(compare); - d3_geo_clipPolygonLinkCircular(subject); - d3_geo_clipPolygonLinkCircular(clip); - if (!subject.length) return; - if (inside) for (var i = 1, e = !inside(clip[0].point), n = clip.length; i < n; ++i) { - clip[i].entry = e = !e; - } - var start = subject[0], current, points, point; - while (1) { - current = start; - while (current.visited) if ((current = current.next) === start) return; - points = current.points; - listener.lineStart(); - do { - current.visited = current.other.visited = true; - if (current.entry) { - if (current.subject) { - for (var i = 0; i < points.length; i++) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.point, current.next.point, 1, listener); - } - current = current.next; - } else { - if (current.subject) { - points = current.prev.points; - for (var i = points.length; --i >= 0; ) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.point, current.prev.point, -1, listener); - } - current = current.prev; - } - current = current.other; - points = current.points; - } while (!current.visited); - listener.lineEnd(); - } - } - function d3_geo_clipPolygonLinkCircular(array) { - if (!(n = array.length)) return; - var n, i = 0, a = array[0], b; - while (++i < n) { - a.next = b = array[i]; - b.prev = a; - a = b; - } - a.next = b = array[0]; - b.prev = a; - } - function d3_geo_clip(pointVisible, clipLine, interpolate, polygonContains) { - return function(listener) { - var line = clipLine(listener); - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - segments = []; - polygon = []; - listener.polygonStart(); - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - segments = d3.merge(segments); - if (segments.length) { - d3_geo_clipPolygon(segments, d3_geo_clipSort, null, interpolate, listener); - } else if (polygonContains(polygon)) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - listener.polygonEnd(); - segments = polygon = null; - }, - sphere: function() { - listener.polygonStart(); - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - listener.polygonEnd(); - } - }; - function point(λ, φ) { - if (pointVisible(λ, φ)) listener.point(λ, φ); - } - function pointLine(λ, φ) { - line.point(λ, φ); - } - function lineStart() { - clip.point = pointLine; - line.lineStart(); - } - function lineEnd() { - clip.point = point; - line.lineEnd(); - } - var segments; - var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygon, ring; - function pointRing(λ, φ) { - ringListener.point(λ, φ); - ring.push([ λ, φ ]); - } - function ringStart() { - ringListener.lineStart(); - ring = []; - } - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringListener.lineEnd(); - var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; - ring.pop(); - polygon.push(ring); - ring = null; - if (!n) return; - if (clean & 1) { - segment = ringSegments[0]; - var n = segment.length - 1, i = -1, point; - listener.lineStart(); - while (++i < n) listener.point((point = segment[i])[0], point[1]); - listener.lineEnd(); - return; - } - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); - } - return clip; - }; - } - function d3_geo_clipSegmentLength1(segment) { - return segment.length > 1; - } - function d3_geo_clipBufferListener() { - var lines = [], line; - return { - lineStart: function() { - lines.push(line = []); - }, - point: function(λ, φ) { - line.push([ λ, φ ]); - }, - lineEnd: d3_noop, - buffer: function() { - var buffer = lines; - lines = []; - line = null; - return buffer; - }, - rejoin: function() { - if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); - } - }; - } - function d3_geo_clipSort(a, b) { - return ((a = a.point)[0] < 0 ? a[1] - π / 2 - ε : π / 2 - a[1]) - ((b = b.point)[0] < 0 ? b[1] - π / 2 - ε : π / 2 - b[1]); - } - function d3_geo_pointInPolygon(point, polygon) { - var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; - d3_geo_areaRingSum.reset(); - for (var i = 0, n = polygon.length; i < n; ++i) { - var ring = polygon[i], m = ring.length; - if (!m) continue; - var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; - while (true) { - if (j === m) j = 0; - point = ring[j]; - var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, antimeridian = Math.abs(dλ) > π, k = sinφ0 * sinφ; - d3_geo_areaRingSum.add(Math.atan2(k * Math.sin(dλ), cosφ0 * cosφ + k * Math.cos(dλ))); - polarAngle += antimeridian ? dλ + (dλ >= 0 ? 2 : -2) * π : dλ; - if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { - var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); - d3_geo_cartesianNormalize(arc); - var intersection = d3_geo_cartesianCross(meridianNormal, arc); - d3_geo_cartesianNormalize(intersection); - var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); - if (parallel > φarc) { - winding += antimeridian ^ dλ >= 0 ? 1 : -1; - } - } - if (!j++) break; - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; - } - } - return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; - } - var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, d3_geo_clipAntimeridianPolygonContains); - function d3_geo_clipAntimeridianLine(listener) { - var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; - return { - lineStart: function() { - listener.lineStart(); - clean = 1; - }, - point: function(λ1, φ1) { - var sλ1 = λ1 > 0 ? π : -π, dλ = Math.abs(λ1 - λ0); - if (Math.abs(dλ - π) < ε) { - listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - listener.point(λ1, φ0); - clean = 0; - } else if (sλ0 !== sλ1 && dλ >= π) { - if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; - if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; - φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - clean = 0; - } - listener.point(λ0 = λ1, φ0 = φ1); - sλ0 = sλ1; - }, - lineEnd: function() { - listener.lineEnd(); - λ0 = φ0 = NaN; - }, - clean: function() { - return 2 - clean; - } - }; - } - function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { - var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); - return Math.abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; - } - function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { - var φ; - if (from == null) { - φ = direction * π / 2; - listener.point(-π, φ); - listener.point(0, φ); - listener.point(π, φ); - listener.point(π, 0); - listener.point(π, -φ); - listener.point(0, -φ); - listener.point(-π, -φ); - listener.point(-π, 0); - listener.point(-π, φ); - } else if (Math.abs(from[0] - to[0]) > ε) { - var s = (from[0] < to[0] ? 1 : -1) * π; - φ = direction * s / 2; - listener.point(-s, φ); - listener.point(0, φ); - listener.point(s, φ); - } else { - listener.point(to[0], to[1]); - } - } - var d3_geo_clipAntimeridianPoint = [ -π, 0 ]; - function d3_geo_clipAntimeridianPolygonContains(polygon) { - return d3_geo_pointInPolygon(d3_geo_clipAntimeridianPoint, polygon); - } - function d3_geo_clipCircle(radius) { - var cr = Math.cos(radius), smallRadius = cr > 0, point = [ radius, 0 ], notHemisphere = Math.abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); - return d3_geo_clip(visible, clipLine, interpolate, polygonContains); - function visible(λ, φ) { - return Math.cos(λ) * Math.cos(φ) > cr; - } - function clipLine(listener) { - var point0, c0, v0, v00, clean; - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(λ, φ) { - var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; - if (!point0 && (v00 = v0 = v)) listener.lineStart(); - if (v !== v0) { - point2 = intersect(point0, point1); - if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { - point1[0] += ε; - point1[1] += ε; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v) { - listener.lineStart(); - point2 = intersect(point1, point0); - listener.point(point2[0], point2[1]); - } else { - point2 = intersect(point0, point1); - listener.point(point2[0], point2[1]); - listener.lineEnd(); - } - point0 = point2; - } else if (notHemisphere && point0 && smallRadius ^ v) { - var t; - if (!(c & c0) && (t = intersect(point1, point0, true))) { - clean = 0; - if (smallRadius) { - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - } else { - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - } - } - } - if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { - listener.point(point1[0], point1[1]); - } - point0 = point1, v0 = v, c0 = c; - }, - lineEnd: function() { - if (v0) listener.lineEnd(); - point0 = null; - }, - clean: function() { - return clean | (v00 && v0) << 1; - } - }; - } - function intersect(a, b, two) { - var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); - var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; - if (!determinant) return !two && a; - var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); - d3_geo_cartesianAdd(A, B); - var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); - if (t2 < 0) return; - var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); - d3_geo_cartesianAdd(q, A); - q = d3_geo_spherical(q); - if (!two) return q; - var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; - if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; - var δλ = λ1 - λ0, polar = Math.abs(δλ - π) < ε, meridian = polar || δλ < ε; - if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; - if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (Math.abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { - var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); - d3_geo_cartesianAdd(q1, A); - return [ q, d3_geo_spherical(q1) ]; - } - } - function code(λ, φ) { - var r = smallRadius ? radius : π - radius, code = 0; - if (λ < -r) code |= 1; else if (λ > r) code |= 2; - if (φ < -r) code |= 4; else if (φ > r) code |= 8; - return code; - } - function polygonContains(polygon) { - return d3_geo_pointInPolygon(point, polygon); - } - } - var d3_geo_clipExtentMAX = 1e9; - d3.geo.clipExtent = function() { - var x0, y0, x1, y1, stream, clip, clipExtent = { - stream: function(output) { - if (stream) stream.valid = false; - stream = clip(output); - stream.valid = true; - return stream; - }, - extent: function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); - if (stream) stream.valid = false, stream = null; - return clipExtent; - } - }; - return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); - }; - function d3_geo_clipExtent(x0, y0, x1, y1) { - return function(listener) { - var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), segments, polygon, ring; - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - listener = bufferListener; - segments = []; - polygon = []; - }, - polygonEnd: function() { - listener = listener_; - if ((segments = d3.merge(segments)).length) { - listener.polygonStart(); - d3_geo_clipPolygon(segments, compare, inside, interpolate, listener); - listener.polygonEnd(); - } else if (insidePolygon([ x0, y0 ])) { - listener.polygonStart(), listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(), listener.polygonEnd(); - } - segments = polygon = ring = null; - } - }; - function inside(point) { - var a = corner(point, -1), i = insidePolygon([ a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0 ]); - return i; - } - function insidePolygon(p) { - var wn = 0, n = polygon.length, y = p[1]; - for (var i = 0; i < n; ++i) { - for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { - b = v[j]; - if (a[1] <= y) { - if (b[1] > y && isLeft(a, b, p) > 0) ++wn; - } else { - if (b[1] <= y && isLeft(a, b, p) < 0) --wn; - } - a = b; - } - } - return wn !== 0; - } - function isLeft(a, b, c) { - return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); - } - function interpolate(from, to, direction, listener) { - var a = 0, a1 = 0; - if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { - do { - listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); - } while ((a = (a + direction + 4) % 4) !== a1); - } else { - listener.point(to[0], to[1]); - } - } - function visible(x, y) { - return x0 <= x && x <= x1 && y0 <= y && y <= y1; - } - function point(x, y) { - if (visible(x, y)) listener.point(x, y); - } - var x__, y__, v__, x_, y_, v_, first; - function lineStart() { - clip.point = linePoint; - if (polygon) polygon.push(ring = []); - first = true; - v_ = false; - x_ = y_ = NaN; - } - function lineEnd() { - if (segments) { - linePoint(x__, y__); - if (v__ && v_) bufferListener.rejoin(); - segments.push(bufferListener.buffer()); - } - clip.point = point; - if (v_) listener.lineEnd(); - } - function linePoint(x, y) { - x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); - y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); - var v = visible(x, y); - if (polygon) ring.push([ x, y ]); - if (first) { - x__ = x, y__ = y, v__ = v; - first = false; - if (v) { - listener.lineStart(); - listener.point(x, y); - } - } else { - if (v && v_) listener.point(x, y); else { - var a = [ x_, y_ ], b = [ x, y ]; - if (clipLine(a, b)) { - if (!v_) { - listener.lineStart(); - listener.point(a[0], a[1]); - } - listener.point(b[0], b[1]); - if (!v) listener.lineEnd(); - } else if (v) { - listener.lineStart(); - listener.point(x, y); - } - } - } - x_ = x, y_ = y, v_ = v; - } - return clip; - }; - function corner(p, direction) { - return Math.abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : Math.abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : Math.abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; - } - function compare(a, b) { - return comparePoints(a.point, b.point); - } - function comparePoints(a, b) { - var ca = corner(a, 1), cb = corner(b, 1); - return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; - } - function clipLine(a, b) { - var dx = b[0] - a[0], dy = b[1] - a[1], t = [ 0, 1 ]; - if (Math.abs(dx) < ε && Math.abs(dy) < ε) return x0 <= a[0] && a[0] <= x1 && y0 <= a[1] && a[1] <= y1; - if (d3_geo_clipExtentT(x0 - a[0], dx, t) && d3_geo_clipExtentT(a[0] - x1, -dx, t) && d3_geo_clipExtentT(y0 - a[1], dy, t) && d3_geo_clipExtentT(a[1] - y1, -dy, t)) { - if (t[1] < 1) { - b[0] = a[0] + t[1] * dx; - b[1] = a[1] + t[1] * dy; - } - if (t[0] > 0) { - a[0] += t[0] * dx; - a[1] += t[0] * dy; - } - return true; - } - return false; - } - } - function d3_geo_clipExtentT(num, denominator, t) { - if (Math.abs(denominator) < ε) return num <= 0; - var u = num / denominator; - if (denominator > 0) { - if (u > t[1]) return false; - if (u > t[0]) t[0] = u; - } else { - if (u < t[0]) return false; - if (u < t[1]) t[1] = u; - } - return true; - } - function d3_geo_compose(a, b) { - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), x && a.invert(x[0], x[1]); - }; - return compose; - } - function d3_geo_conic(projectAt) { - var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); - p.parallels = function(_) { - if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; - return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); - }; - return p; - } - function d3_geo_conicEqualArea(φ0, φ1) { - var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; - function forward(λ, φ) { - var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; - return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = ρ0 - y; - return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; - }; - return forward; - } - (d3.geo.conicEqualArea = function() { - return d3_geo_conic(d3_geo_conicEqualArea); - }).raw = d3_geo_conicEqualArea; - d3.geo.albers = function() { - return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); - }; - d3.geo.albersUsa = function() { - var lower48 = d3.geo.albers(); - var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); - var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); - var point, pointStream = { - point: function(x, y) { - point = [ x, y ]; - } - }, lower48Point, alaskaPoint, hawaiiPoint; - function albersUsa(coordinates) { - var x = coordinates[0], y = coordinates[1]; - point = null; - (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); - return point; - } - albersUsa.invert = function(coordinates) { - var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; - return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); - }; - albersUsa.stream = function(stream) { - var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); - return { - point: function(x, y) { - lower48Stream.point(x, y); - alaskaStream.point(x, y); - hawaiiStream.point(x, y); - }, - sphere: function() { - lower48Stream.sphere(); - alaskaStream.sphere(); - hawaiiStream.sphere(); - }, - lineStart: function() { - lower48Stream.lineStart(); - alaskaStream.lineStart(); - hawaiiStream.lineStart(); - }, - lineEnd: function() { - lower48Stream.lineEnd(); - alaskaStream.lineEnd(); - hawaiiStream.lineEnd(); - }, - polygonStart: function() { - lower48Stream.polygonStart(); - alaskaStream.polygonStart(); - hawaiiStream.polygonStart(); - }, - polygonEnd: function() { - lower48Stream.polygonEnd(); - alaskaStream.polygonEnd(); - hawaiiStream.polygonEnd(); - } - }; - }; - albersUsa.precision = function(_) { - if (!arguments.length) return lower48.precision(); - lower48.precision(_); - alaska.precision(_); - hawaii.precision(_); - return albersUsa; - }; - albersUsa.scale = function(_) { - if (!arguments.length) return lower48.scale(); - lower48.scale(_); - alaska.scale(_ * .35); - hawaii.scale(_); - return albersUsa.translate(lower48.translate()); - }; - albersUsa.translate = function(_) { - if (!arguments.length) return lower48.translate(); - var k = lower48.scale(), x = +_[0], y = +_[1]; - lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; - alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - return albersUsa; - }; - return albersUsa.scale(1070); - }; - var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_pathAreaPolygon = 0; - d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; - }, - polygonEnd: function() { - d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; - d3_geo_pathAreaSum += Math.abs(d3_geo_pathAreaPolygon / 2); - } - }; - function d3_geo_pathAreaRingStart() { - var x00, y00, x0, y0; - d3_geo_pathArea.point = function(x, y) { - d3_geo_pathArea.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - function nextPoint(x, y) { - d3_geo_pathAreaPolygon += y0 * x - x0 * y; - x0 = x, y0 = y; - } - d3_geo_pathArea.lineEnd = function() { - nextPoint(x00, y00); - }; - } - var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; - var d3_geo_pathBounds = { - point: d3_geo_pathBoundsPoint, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_pathBoundsPoint(x, y) { - if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; - if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; - if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; - if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; - } - function d3_geo_pathBuffer() { - var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointCircle = d3_geo_pathBufferCircle(_); - return stream; - }, - result: function() { - if (buffer.length) { - var result = buffer.join(""); - buffer = []; - return result; - } - } - }; - function point(x, y) { - buffer.push("M", x, ",", y, pointCircle); - } - function pointLineStart(x, y) { - buffer.push("M", x, ",", y); - stream.point = pointLine; - } - function pointLine(x, y) { - buffer.push("L", x, ",", y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - buffer.push("Z"); - } - return stream; - } - function d3_geo_pathBufferCircle(radius) { - return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; - } - var d3_geo_pathCentroid = { - point: d3_geo_pathCentroidPoint, - lineStart: d3_geo_pathCentroidLineStart, - lineEnd: d3_geo_pathCentroidLineEnd, - polygonStart: function() { - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; - }, - polygonEnd: function() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; - d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; - } - }; - function d3_geo_pathCentroidPoint(x, y) { - d3_geo_centroidX0 += x; - d3_geo_centroidY0 += y; - ++d3_geo_centroidZ0; - } - function d3_geo_pathCentroidLineStart() { - var x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - } - function d3_geo_pathCentroidLineEnd() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - } - function d3_geo_pathCentroidRingStart() { - var x00, y00, x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - z = y0 * x - x0 * y; - d3_geo_centroidX2 += z * (x0 + x); - d3_geo_centroidY2 += z * (y0 + y); - d3_geo_centroidZ2 += z * 3; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - d3_geo_pathCentroid.lineEnd = function() { - nextPoint(x00, y00); - }; - } - function d3_geo_pathContext(context) { - var pointRadius = 4.5; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointRadius = _; - return stream; - }, - result: d3_noop - }; - function point(x, y) { - context.moveTo(x, y); - context.arc(x, y, pointRadius, 0, 2 * π); - } - function pointLineStart(x, y) { - context.moveTo(x, y); - stream.point = pointLine; - } - function pointLine(x, y) { - context.lineTo(x, y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - context.closePath(); - } - return stream; - } - function d3_geo_resample(project) { - var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; - function resample(stream) { - var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; - var resample = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - stream.polygonStart(); - resample.lineStart = ringStart; - }, - polygonEnd: function() { - stream.polygonEnd(); - resample.lineStart = lineStart; - } - }; - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } - function lineStart() { - x0 = NaN; - resample.point = linePoint; - stream.lineStart(); - } - function linePoint(λ, φ) { - var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); - resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } - function lineEnd() { - resample.point = point; - stream.lineEnd(); - } - function ringStart() { - lineStart(); - resample.point = ringPoint; - resample.lineEnd = ringEnd; - } - function ringPoint(λ, φ) { - linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resample.point = linePoint; - } - function ringEnd() { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); - resample.lineEnd = lineEnd; - lineEnd(); - } - return resample; - } - function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; - if (d2 > 4 * δ2 && depth--) { - var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); - } - } - } - resample.precision = function(_) { - if (!arguments.length) return Math.sqrt(δ2); - maxDepth = (δ2 = _ * _) > 0 && 16; - return resample; - }; - return resample; - } - d3.geo.transform = function(methods) { - return { - stream: function(stream) { - var transform = new d3_geo_transform(stream); - for (var k in methods) transform[k] = methods[k]; - return transform; - } - }; - }; - function d3_geo_transform(stream) { - this.stream = stream; - } - d3_geo_transform.prototype = { - point: function(x, y) { - this.stream.point(x, y); - }, - sphere: function() { - this.stream.sphere(); - }, - lineStart: function() { - this.stream.lineStart(); - }, - lineEnd: function() { - this.stream.lineEnd(); - }, - polygonStart: function() { - this.stream.polygonStart(); - }, - polygonEnd: function() { - this.stream.polygonEnd(); - } - }; - d3.geo.path = function() { - var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; - function path(object) { - if (object) { - if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); - if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); - d3.geo.stream(object, cacheStream); - } - return contextStream.result(); - } - path.area = function(object) { - d3_geo_pathAreaSum = 0; - d3.geo.stream(object, projectStream(d3_geo_pathArea)); - return d3_geo_pathAreaSum; - }; - path.centroid = function(object) { - d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); - return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; - }; - path.bounds = function(object) { - d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); - d3.geo.stream(object, projectStream(d3_geo_pathBounds)); - return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; - }; - path.projection = function(_) { - if (!arguments.length) return projection; - projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; - return reset(); - }; - path.context = function(_) { - if (!arguments.length) return context; - contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); - if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); - return reset(); - }; - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); - return path; - }; - function reset() { - cacheStream = null; - return path; - } - return path.projection(d3.geo.albersUsa()).context(null); - }; - function d3_geo_pathProjectStream(project) { - var resample = d3_geo_resample(function(x, y) { - return project([ x * d3_degrees, y * d3_degrees ]); - }); - return function(stream) { - var transform = new d3_geo_transform(stream = resample(stream)); - transform.point = function(x, y) { - stream.point(x * d3_radians, y * d3_radians); - }; - return transform; - }; - } - d3.geo.projection = d3_geo_projection; - d3.geo.projectionMutator = d3_geo_projectionMutator; - function d3_geo_projection(project) { - return d3_geo_projectionMutator(function() { - return project; - })(); - } - function d3_geo_projectionMutator(projectAt) { - var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { - x = project(x, y); - return [ x[0] * k + δx, δy - x[1] * k ]; - }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; - function projection(point) { - point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); - return [ point[0] * k + δx, δy - point[1] * k ]; - } - function invert(point) { - point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); - return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; - } - projection.stream = function(output) { - if (stream) stream.valid = false; - stream = d3_geo_projectionRadiansRotate(rotate, preclip(projectResample(postclip(output)))); - stream.valid = true; - return stream; - }; - projection.clipAngle = function(_) { - if (!arguments.length) return clipAngle; - preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); - return invalidate(); - }; - projection.clipExtent = function(_) { - if (!arguments.length) return clipExtent; - clipExtent = _; - postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; - return invalidate(); - }; - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return reset(); - }; - projection.translate = function(_) { - if (!arguments.length) return [ x, y ]; - x = +_[0]; - y = +_[1]; - return reset(); - }; - projection.center = function(_) { - if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; - λ = _[0] % 360 * d3_radians; - φ = _[1] % 360 * d3_radians; - return reset(); - }; - projection.rotate = function(_) { - if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; - δλ = _[0] % 360 * d3_radians; - δφ = _[1] % 360 * d3_radians; - δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; - return reset(); - }; - d3.rebind(projection, projectResample, "precision"); - function reset() { - projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); - var center = project(λ, φ); - δx = x - center[0] * k; - δy = y + center[1] * k; - return invalidate(); - } - function invalidate() { - if (stream) stream.valid = false, stream = null; - return projection; - } - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return reset(); - }; - } - function d3_geo_projectionRadiansRotate(rotate, stream) { - var transform = new d3_geo_transform(stream); - transform.point = function(x, y) { - y = rotate(x * d3_radians, y * d3_radians), x = y[0]; - stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]); - }; - return transform; - } - function d3_geo_equirectangular(λ, φ) { - return [ λ, φ ]; - } - (d3.geo.equirectangular = function() { - return d3_geo_projection(d3_geo_equirectangular); - }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; - d3.geo.rotation = function(rotate) { - rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); - function forward(coordinates) { - coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - } - forward.invert = function(coordinates) { - coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - }; - return forward; - }; - function d3_geo_rotation(δλ, δφ, δγ) { - return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_equirectangular; - } - function d3_geo_forwardRotationλ(δλ) { - return function(λ, φ) { - return λ += δλ, [ λ > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ ]; - }; - } - function d3_geo_rotationλ(δλ) { - var rotation = d3_geo_forwardRotationλ(δλ); - rotation.invert = d3_geo_forwardRotationλ(-δλ); - return rotation; - } - function d3_geo_rotationφγ(δφ, δγ) { - var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); - function rotation(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; - return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; - } - rotation.invert = function(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; - return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; - }; - return rotation; - } - d3.geo.circle = function() { - var origin = [ 0, 0 ], angle, precision = 6, interpolate; - function circle() { - var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; - interpolate(null, null, 1, { - point: function(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= d3_degrees, x[1] *= d3_degrees; - } - }); - return { - type: "Polygon", - coordinates: [ ring ] - }; - } - circle.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return circle; - }; - circle.angle = function(x) { - if (!arguments.length) return angle; - interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); - return circle; - }; - circle.precision = function(_) { - if (!arguments.length) return precision; - interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); - return circle; - }; - return circle.angle(90); - }; - function d3_geo_circleInterpolate(radius, precision) { - var cr = Math.cos(radius), sr = Math.sin(radius); - return function(from, to, direction, listener) { - var step = direction * precision; - if (from != null) { - from = d3_geo_circleAngle(cr, from); - to = d3_geo_circleAngle(cr, to); - if (direction > 0 ? from < to : from > to) from += direction * 2 * π; - } else { - from = radius + direction * 2 * π; - to = radius - .5 * step; - } - for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { - listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); - } - }; - } - function d3_geo_circleAngle(cr, point) { - var a = d3_geo_cartesian(point); - a[0] -= cr; - d3_geo_cartesianNormalize(a); - var angle = d3_acos(-a[1]); - return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); - } - d3.geo.distance = function(a, b) { - var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; - return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); - }; - d3.geo.graticule = function() { - var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; - function graticule() { - return { - type: "MultiLineString", - coordinates: lines() - }; - } - function lines() { - return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { - return Math.abs(x % DX) > ε; - }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { - return Math.abs(y % DY) > ε; - }).map(y)); - } - graticule.lines = function() { - return lines().map(function(coordinates) { - return { - type: "LineString", - coordinates: coordinates - }; - }); - }; - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] - }; - }; - graticule.extent = function(_) { - if (!arguments.length) return graticule.minorExtent(); - return graticule.majorExtent(_).minorExtent(_); - }; - graticule.majorExtent = function(_) { - if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; - X0 = +_[0][0], X1 = +_[1][0]; - Y0 = +_[0][1], Y1 = +_[1][1]; - if (X0 > X1) _ = X0, X0 = X1, X1 = _; - if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; - return graticule.precision(precision); - }; - graticule.minorExtent = function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; - graticule.step = function(_) { - if (!arguments.length) return graticule.minorStep(); - return graticule.majorStep(_).minorStep(_); - }; - graticule.majorStep = function(_) { - if (!arguments.length) return [ DX, DY ]; - DX = +_[0], DY = +_[1]; - return graticule; - }; - graticule.minorStep = function(_) { - if (!arguments.length) return [ dx, dy ]; - dx = +_[0], dy = +_[1]; - return graticule; - }; - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = d3_geo_graticuleX(y0, y1, 90); - y = d3_geo_graticuleY(x0, x1, precision); - X = d3_geo_graticuleX(Y0, Y1, 90); - Y = d3_geo_graticuleY(X0, X1, precision); - return graticule; - }; - return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); - }; - function d3_geo_graticuleX(y0, y1, dy) { - var y = d3.range(y0, y1 - ε, dy).concat(y1); - return function(x) { - return y.map(function(y) { - return [ x, y ]; - }); - }; - } - function d3_geo_graticuleY(x0, x1, dx) { - var x = d3.range(x0, x1 - ε, dx).concat(x1); - return function(y) { - return x.map(function(x) { - return [ x, y ]; - }); - }; - } - function d3_source(d) { - return d.source; - } - function d3_target(d) { - return d.target; - } - d3.geo.greatArc = function() { - var source = d3_source, source_, target = d3_target, target_; - function greatArc() { - return { - type: "LineString", - coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] - }; - } - greatArc.distance = function() { - return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); - }; - greatArc.source = function(_) { - if (!arguments.length) return source; - source = _, source_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.target = function(_) { - if (!arguments.length) return target; - target = _, target_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.precision = function() { - return arguments.length ? greatArc : 0; - }; - return greatArc; - }; - d3.geo.interpolate = function(source, target) { - return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); - }; - function d3_geo_interpolate(x0, y0, x1, y1) { - var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); - var interpolate = d ? function(t) { - var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; - return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; - } : function() { - return [ x0 * d3_degrees, y0 * d3_degrees ]; - }; - interpolate.distance = d; - return interpolate; - } - d3.geo.length = function(object) { - d3_geo_lengthSum = 0; - d3.geo.stream(object, d3_geo_length); - return d3_geo_lengthSum; - }; - var d3_geo_lengthSum; - var d3_geo_length = { - sphere: d3_noop, - point: d3_noop, - lineStart: d3_geo_lengthLineStart, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_lengthLineStart() { - var λ0, sinφ0, cosφ0; - d3_geo_length.point = function(λ, φ) { - λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); - d3_geo_length.point = nextPoint; - }; - d3_geo_length.lineEnd = function() { - d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; - }; - function nextPoint(λ, φ) { - var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = Math.abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); - d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; - } - } - function d3_geo_azimuthal(scale, angle) { - function azimuthal(λ, φ) { - var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); - return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; - } - azimuthal.invert = function(x, y) { - var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); - return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; - }; - return azimuthal; - } - var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { - return Math.sqrt(2 / (1 + cosλcosφ)); - }, function(ρ) { - return 2 * Math.asin(ρ / 2); - }); - (d3.geo.azimuthalEqualArea = function() { - return d3_geo_projection(d3_geo_azimuthalEqualArea); - }).raw = d3_geo_azimuthalEqualArea; - var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { - var c = Math.acos(cosλcosφ); - return c && c / Math.sin(c); - }, d3_identity); - (d3.geo.azimuthalEquidistant = function() { - return d3_geo_projection(d3_geo_azimuthalEquidistant); - }).raw = d3_geo_azimuthalEquidistant; - function d3_geo_conicConformal(φ0, φ1) { - var cosφ0 = Math.cos(φ0), t = function(φ) { - return Math.tan(π / 4 + φ / 2); - }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; - if (!n) return d3_geo_mercator; - function forward(λ, φ) { - var ρ = Math.abs(Math.abs(φ) - π / 2) < ε ? 0 : F / Math.pow(t(φ), n); - return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); - return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - π / 2 ]; - }; - return forward; - } - (d3.geo.conicConformal = function() { - return d3_geo_conic(d3_geo_conicConformal); - }).raw = d3_geo_conicConformal; - function d3_geo_conicEquidistant(φ0, φ1) { - var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; - if (Math.abs(n) < ε) return d3_geo_equirectangular; - function forward(λ, φ) { - var ρ = G - φ; - return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = G - y; - return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; - }; - return forward; - } - (d3.geo.conicEquidistant = function() { - return d3_geo_conic(d3_geo_conicEquidistant); - }).raw = d3_geo_conicEquidistant; - var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / cosλcosφ; - }, Math.atan); - (d3.geo.gnomonic = function() { - return d3_geo_projection(d3_geo_gnomonic); - }).raw = d3_geo_gnomonic; - function d3_geo_mercator(λ, φ) { - return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; - } - d3_geo_mercator.invert = function(x, y) { - return [ x, 2 * Math.atan(Math.exp(y)) - π / 2 ]; - }; - function d3_geo_mercatorProjection(project) { - var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; - m.scale = function() { - var v = scale.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.translate = function() { - var v = translate.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.clipExtent = function(_) { - var v = clipExtent.apply(m, arguments); - if (v === m) { - if (clipAuto = _ == null) { - var k = π * scale(), t = translate(); - clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); - } - } else if (clipAuto) { - v = null; - } - return v; - }; - return m.clipExtent(null); - } - (d3.geo.mercator = function() { - return d3_geo_mercatorProjection(d3_geo_mercator); - }).raw = d3_geo_mercator; - var d3_geo_orthographic = d3_geo_azimuthal(function() { - return 1; - }, Math.asin); - (d3.geo.orthographic = function() { - return d3_geo_projection(d3_geo_orthographic); - }).raw = d3_geo_orthographic; - var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / (1 + cosλcosφ); - }, function(ρ) { - return 2 * Math.atan(ρ); - }); - (d3.geo.stereographic = function() { - return d3_geo_projection(d3_geo_stereographic); - }).raw = d3_geo_stereographic; - function d3_geo_transverseMercator(λ, φ) { - var B = Math.cos(φ) * Math.sin(λ); - return [ Math.log((1 + B) / (1 - B)) / 2, Math.atan2(Math.tan(φ), Math.cos(λ)) ]; - } - d3_geo_transverseMercator.invert = function(x, y) { - return [ Math.atan2(d3_sinh(x), Math.cos(y)), d3_asin(Math.sin(y) / d3_cosh(x)) ]; - }; - (d3.geo.transverseMercator = function() { - return d3_geo_mercatorProjection(d3_geo_transverseMercator); - }).raw = d3_geo_transverseMercator; - d3.geom = {}; - d3.svg = {}; - function d3_svg_line(projection) { - var x = d3_svg_lineX, y = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; - function line(data) { - var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); - function segment() { - segments.push("M", interpolate(projection(points), tension)); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); - } else if (points.length) { - segment(); - points = []; - } - } - if (points.length) segment(); - return segments.length ? segments.join("") : null; - } - line.x = function(_) { - if (!arguments.length) return x; - x = _; - return line; - }; - line.y = function(_) { - if (!arguments.length) return y; - y = _; - return line; - }; - line.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return line; - }; - line.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - return line; - }; - line.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return line; - }; - return line; - } - d3.svg.line = function() { - return d3_svg_line(d3_identity); - }; - function d3_svg_lineX(d) { - return d[0]; - } - function d3_svg_lineY(d) { - return d[1]; - } - var d3_svg_lineInterpolators = d3.map({ - linear: d3_svg_lineLinear, - "linear-closed": d3_svg_lineLinearClosed, - step: d3_svg_lineStep, - "step-before": d3_svg_lineStepBefore, - "step-after": d3_svg_lineStepAfter, - basis: d3_svg_lineBasis, - "basis-open": d3_svg_lineBasisOpen, - "basis-closed": d3_svg_lineBasisClosed, - bundle: d3_svg_lineBundle, - cardinal: d3_svg_lineCardinal, - "cardinal-open": d3_svg_lineCardinalOpen, - "cardinal-closed": d3_svg_lineCardinalClosed, - monotone: d3_svg_lineMonotone - }); - d3_svg_lineInterpolators.forEach(function(key, value) { - value.key = key; - value.closed = /-closed$/.test(key); - }); - function d3_svg_lineLinear(points) { - return points.join("L"); - } - function d3_svg_lineLinearClosed(points) { - return d3_svg_lineLinear(points) + "Z"; - } - function d3_svg_lineStep(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); - if (n > 1) path.push("H", p[0]); - return path.join(""); - } - function d3_svg_lineStepBefore(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); - return path.join(""); - } - function d3_svg_lineStepAfter(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); - return path.join(""); - } - function d3_svg_lineCardinalOpen(points, tension) { - return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineCardinalClosed(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), - points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); - } - function d3_svg_lineCardinal(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineHermite(points, tangents) { - if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { - return d3_svg_lineLinear(points); - } - var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; - if (quad) { - path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; - p0 = points[1]; - pi = 2; - } - if (tangents.length > 1) { - t = tangents[1]; - p = points[pi]; - pi++; - path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - for (var i = 2; i < tangents.length; i++, pi++) { - p = points[pi]; - t = tangents[i]; - path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - } - } - if (quad) { - var lp = points[pi]; - path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; - } - return path; - } - function d3_svg_lineCardinalTangents(points, tension) { - var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; - while (++i < n) { - p0 = p1; - p1 = p2; - p2 = points[i]; - tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); - } - return tangents; - } - function d3_svg_lineBasis(points) { - if (points.length < 3) return d3_svg_lineLinear(points); - var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - points.push(points[n - 1]); - while (++i <= n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - points.pop(); - path.push("L", pi); - return path.join(""); - } - function d3_svg_lineBasisOpen(points) { - if (points.length < 4) return d3_svg_lineLinear(points); - var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; - while (++i < 3) { - pi = points[i]; - px.push(pi[0]); - py.push(pi[1]); - } - path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); - --i; - while (++i < n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBasisClosed(points) { - var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; - while (++i < 4) { - pi = points[i % n]; - px.push(pi[0]); - py.push(pi[1]); - } - path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - --i; - while (++i < m) { - pi = points[i % n]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBundle(points, tension) { - var n = points.length - 1; - if (n) { - var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; - while (++i <= n) { - p = points[i]; - t = i / n; - p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); - p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); - } - } - return d3_svg_lineBasis(points); - } - function d3_svg_lineDot4(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; - } - var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; - function d3_svg_lineBasisBezier(path, x, y) { - path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); - } - function d3_svg_lineSlope(p0, p1) { - return (p1[1] - p0[1]) / (p1[0] - p0[0]); - } - function d3_svg_lineFiniteDifferences(points) { - var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); - while (++i < j) { - m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; - } - m[i] = d; - return m; - } - function d3_svg_lineMonotoneTangents(points) { - var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; - while (++i < j) { - d = d3_svg_lineSlope(points[i], points[i + 1]); - if (Math.abs(d) < 1e-6) { - m[i] = m[i + 1] = 0; - } else { - a = m[i] / d; - b = m[i + 1] / d; - s = a * a + b * b; - if (s > 9) { - s = d * 3 / Math.sqrt(s); - m[i] = s * a; - m[i + 1] = s * b; - } - } - } - i = -1; - while (++i <= j) { - s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); - tangents.push([ s || 0, m[i] * s || 0 ]); - } - return tangents; - } - function d3_svg_lineMonotone(points) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); - } - d3.geom.hull = function(vertices) { - var x = d3_svg_lineX, y = d3_svg_lineY; - if (arguments.length) return hull(vertices); - function hull(data) { - if (data.length < 3) return []; - var fx = d3_functor(x), fy = d3_functor(y), n = data.length, vertices, plen = n - 1, points = [], stack = [], d, i, j, h = 0, x1, y1, x2, y2, u, v, a, sp; - if (fx === d3_svg_lineX && y === d3_svg_lineY) vertices = data; else for (i = 0, - vertices = []; i < n; ++i) { - vertices.push([ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]); - } - for (i = 1; i < n; ++i) { - if (vertices[i][1] < vertices[h][1] || vertices[i][1] == vertices[h][1] && vertices[i][0] < vertices[h][0]) h = i; - } - for (i = 0; i < n; ++i) { - if (i === h) continue; - y1 = vertices[i][1] - vertices[h][1]; - x1 = vertices[i][0] - vertices[h][0]; - points.push({ - angle: Math.atan2(y1, x1), - index: i - }); - } - points.sort(function(a, b) { - return a.angle - b.angle; - }); - a = points[0].angle; - v = points[0].index; - u = 0; - for (i = 1; i < plen; ++i) { - j = points[i].index; - if (a == points[i].angle) { - x1 = vertices[v][0] - vertices[h][0]; - y1 = vertices[v][1] - vertices[h][1]; - x2 = vertices[j][0] - vertices[h][0]; - y2 = vertices[j][1] - vertices[h][1]; - if (x1 * x1 + y1 * y1 >= x2 * x2 + y2 * y2) { - points[i].index = -1; - continue; - } else { - points[u].index = -1; - } - } - a = points[i].angle; - u = i; - v = j; - } - stack.push(h); - for (i = 0, j = 0; i < 2; ++j) { - if (points[j].index > -1) { - stack.push(points[j].index); - i++; - } - } - sp = stack.length; - for (;j < plen; ++j) { - if (points[j].index < 0) continue; - while (!d3_geom_hullCCW(stack[sp - 2], stack[sp - 1], points[j].index, vertices)) { - --sp; - } - stack[sp++] = points[j].index; - } - var poly = []; - for (i = sp - 1; i >= 0; --i) poly.push(data[stack[i]]); - return poly; - } - hull.x = function(_) { - return arguments.length ? (x = _, hull) : x; - }; - hull.y = function(_) { - return arguments.length ? (y = _, hull) : y; - }; - return hull; - }; - function d3_geom_hullCCW(i1, i2, i3, v) { - var t, a, b, c, d, e, f; - t = v[i1]; - a = t[0]; - b = t[1]; - t = v[i2]; - c = t[0]; - d = t[1]; - t = v[i3]; - e = t[0]; - f = t[1]; - return (f - b) * (c - a) - (d - b) * (e - a) > 0; - } - d3.geom.polygon = function(coordinates) { - d3_subclass(coordinates, d3_geom_polygonPrototype); - return coordinates; - }; - var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; - d3_geom_polygonPrototype.area = function() { - var i = -1, n = this.length, a, b = this[n - 1], area = 0; - while (++i < n) { - a = b; - b = this[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - return area * .5; - }; - d3_geom_polygonPrototype.centroid = function(k) { - var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; - if (!arguments.length) k = -1 / (6 * this.area()); - while (++i < n) { - a = b; - b = this[i]; - c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } - return [ x * k, y * k ]; - }; - d3_geom_polygonPrototype.clip = function(subject) { - var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; - while (++i < n) { - input = subject.slice(); - subject.length = 0; - b = this[i]; - c = input[(m = input.length - closed) - 1]; - j = -1; - while (++j < m) { - d = input[j]; - if (d3_geom_polygonInside(d, a, b)) { - if (!d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - subject.push(d); - } else if (d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - c = d; - } - if (closed) subject.push(subject[0]); - a = b; - } - return subject; - }; - function d3_geom_polygonInside(p, a, b) { - return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); - } - function d3_geom_polygonIntersect(c, d, a, b) { - var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); - return [ x1 + ua * x21, y1 + ua * y21 ]; - } - function d3_geom_polygonClosed(coordinates) { - var a = coordinates[0], b = coordinates[coordinates.length - 1]; - return !(a[0] - b[0] || a[1] - b[1]); - } - d3.geom.delaunay = function(vertices) { - var edges = vertices.map(function() { - return []; - }), triangles = []; - d3_geom_voronoiTessellate(vertices, function(e) { - edges[e.region.l.index].push(vertices[e.region.r.index]); - }); - edges.forEach(function(edge, i) { - var v = vertices[i], cx = v[0], cy = v[1]; - edge.forEach(function(v) { - v.angle = Math.atan2(v[0] - cx, v[1] - cy); - }); - edge.sort(function(a, b) { - return a.angle - b.angle; - }); - for (var j = 0, m = edge.length - 1; j < m; j++) { - triangles.push([ v, edge[j], edge[j + 1] ]); - } - }); - return triangles; - }; - d3.geom.voronoi = function(points) { - var x = d3_svg_lineX, y = d3_svg_lineY, clipPolygon = null; - if (arguments.length) return voronoi(points); - function voronoi(data) { - var points, polygons = data.map(function() { - return []; - }), fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length, Z = 1e6; - if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; else for (points = new Array(n), - i = 0; i < n; ++i) { - points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]; - } - d3_geom_voronoiTessellate(points, function(e) { - var s1, s2, x1, x2, y1, y2; - if (e.a === 1 && e.b >= 0) { - s1 = e.ep.r; - s2 = e.ep.l; - } else { - s1 = e.ep.l; - s2 = e.ep.r; - } - if (e.a === 1) { - y1 = s1 ? s1.y : -Z; - x1 = e.c - e.b * y1; - y2 = s2 ? s2.y : Z; - x2 = e.c - e.b * y2; - } else { - x1 = s1 ? s1.x : -Z; - y1 = e.c - e.a * x1; - x2 = s2 ? s2.x : Z; - y2 = e.c - e.a * x2; - } - var v1 = [ x1, y1 ], v2 = [ x2, y2 ]; - polygons[e.region.l.index].push(v1, v2); - polygons[e.region.r.index].push(v1, v2); - }); - polygons = polygons.map(function(polygon, i) { - var cx = points[i][0], cy = points[i][1], angle = polygon.map(function(v) { - return Math.atan2(v[0] - cx, v[1] - cy); - }), order = d3.range(polygon.length).sort(function(a, b) { - return angle[a] - angle[b]; - }); - return order.filter(function(d, i) { - return !i || angle[d] - angle[order[i - 1]] > ε; - }).map(function(d) { - return polygon[d]; - }); - }); - polygons.forEach(function(polygon, i) { - var n = polygon.length; - if (!n) return polygon.push([ -Z, -Z ], [ -Z, Z ], [ Z, Z ], [ Z, -Z ]); - if (n > 2) return; - var p0 = points[i], p1 = polygon[0], p2 = polygon[1], x0 = p0[0], y0 = p0[1], x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], dx = Math.abs(x2 - x1), dy = y2 - y1; - if (Math.abs(dy) < ε) { - var y = y0 < y1 ? -Z : Z; - polygon.push([ -Z, y ], [ Z, y ]); - } else if (dx < ε) { - var x = x0 < x1 ? -Z : Z; - polygon.push([ x, -Z ], [ x, Z ]); - } else { - var y = (x2 - x1) * (y1 - y0) < (x1 - x0) * (y2 - y1) ? Z : -Z, z = Math.abs(dy) - dx; - if (Math.abs(z) < ε) { - polygon.push([ dy < 0 ? y : -y, y ]); - } else { - if (z > 0) y *= -1; - polygon.push([ -Z, y ], [ Z, y ]); - } - } - }); - if (clipPolygon) for (i = 0; i < n; ++i) clipPolygon.clip(polygons[i]); - for (i = 0; i < n; ++i) polygons[i].point = data[i]; - return polygons; - } - voronoi.x = function(_) { - return arguments.length ? (x = _, voronoi) : x; - }; - voronoi.y = function(_) { - return arguments.length ? (y = _, voronoi) : y; - }; - voronoi.clipExtent = function(_) { - if (!arguments.length) return clipPolygon && [ clipPolygon[0], clipPolygon[2] ]; - if (_ == null) clipPolygon = null; else { - var x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], y2 = +_[1][1]; - clipPolygon = d3.geom.polygon([ [ x1, y1 ], [ x1, y2 ], [ x2, y2 ], [ x2, y1 ] ]); - } - return voronoi; - }; - voronoi.size = function(_) { - if (!arguments.length) return clipPolygon && clipPolygon[2]; - return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); - }; - voronoi.links = function(data) { - var points, graph = data.map(function() { - return []; - }), links = [], fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length; - if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; else for (points = new Array(n), - i = 0; i < n; ++i) { - points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]; - } - d3_geom_voronoiTessellate(points, function(e) { - var l = e.region.l.index, r = e.region.r.index; - if (graph[l][r]) return; - graph[l][r] = graph[r][l] = true; - links.push({ - source: data[l], - target: data[r] - }); - }); - return links; - }; - voronoi.triangles = function(data) { - if (x === d3_svg_lineX && y === d3_svg_lineY) return d3.geom.delaunay(data); - var points = new Array(n), fx = d3_functor(x), fy = d3_functor(y), d, i = -1, n = data.length; - while (++i < n) { - (points[i] = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]).data = d; - } - return d3.geom.delaunay(points).map(function(triangle) { - return triangle.map(function(point) { - return point.data; - }); - }); - }; - return voronoi; - }; - var d3_geom_voronoiOpposite = { - l: "r", - r: "l" - }; - function d3_geom_voronoiTessellate(points, callback) { - var Sites = { - list: points.map(function(v, i) { - return { - index: i, - x: v[0], - y: v[1] - }; - }).sort(function(a, b) { - return a.y < b.y ? -1 : a.y > b.y ? 1 : a.x < b.x ? -1 : a.x > b.x ? 1 : 0; - }), - bottomSite: null - }; - var EdgeList = { - list: [], - leftEnd: null, - rightEnd: null, - init: function() { - EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l"); - EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l"); - EdgeList.leftEnd.r = EdgeList.rightEnd; - EdgeList.rightEnd.l = EdgeList.leftEnd; - EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd); - }, - createHalfEdge: function(edge, side) { - return { - edge: edge, - side: side, - vertex: null, - l: null, - r: null - }; - }, - insert: function(lb, he) { - he.l = lb; - he.r = lb.r; - lb.r.l = he; - lb.r = he; - }, - leftBound: function(p) { - var he = EdgeList.leftEnd; - do { - he = he.r; - } while (he != EdgeList.rightEnd && Geom.rightOf(he, p)); - he = he.l; - return he; - }, - del: function(he) { - he.l.r = he.r; - he.r.l = he.l; - he.edge = null; - }, - right: function(he) { - return he.r; - }, - left: function(he) { - return he.l; - }, - leftRegion: function(he) { - return he.edge == null ? Sites.bottomSite : he.edge.region[he.side]; - }, - rightRegion: function(he) { - return he.edge == null ? Sites.bottomSite : he.edge.region[d3_geom_voronoiOpposite[he.side]]; - } - }; - var Geom = { - bisect: function(s1, s2) { - var newEdge = { - region: { - l: s1, - r: s2 - }, - ep: { - l: null, - r: null - } - }; - var dx = s2.x - s1.x, dy = s2.y - s1.y, adx = dx > 0 ? dx : -dx, ady = dy > 0 ? dy : -dy; - newEdge.c = s1.x * dx + s1.y * dy + (dx * dx + dy * dy) * .5; - if (adx > ady) { - newEdge.a = 1; - newEdge.b = dy / dx; - newEdge.c /= dx; - } else { - newEdge.b = 1; - newEdge.a = dx / dy; - newEdge.c /= dy; - } - return newEdge; - }, - intersect: function(el1, el2) { - var e1 = el1.edge, e2 = el2.edge; - if (!e1 || !e2 || e1.region.r == e2.region.r) { - return null; - } - var d = e1.a * e2.b - e1.b * e2.a; - if (Math.abs(d) < 1e-10) { - return null; - } - var xint = (e1.c * e2.b - e2.c * e1.b) / d, yint = (e2.c * e1.a - e1.c * e2.a) / d, e1r = e1.region.r, e2r = e2.region.r, el, e; - if (e1r.y < e2r.y || e1r.y == e2r.y && e1r.x < e2r.x) { - el = el1; - e = e1; - } else { - el = el2; - e = e2; - } - var rightOfSite = xint >= e.region.r.x; - if (rightOfSite && el.side === "l" || !rightOfSite && el.side === "r") { - return null; - } - return { - x: xint, - y: yint - }; - }, - rightOf: function(he, p) { - var e = he.edge, topsite = e.region.r, rightOfSite = p.x > topsite.x; - if (rightOfSite && he.side === "l") { - return 1; - } - if (!rightOfSite && he.side === "r") { - return 0; - } - if (e.a === 1) { - var dyp = p.y - topsite.y, dxp = p.x - topsite.x, fast = 0, above = 0; - if (!rightOfSite && e.b < 0 || rightOfSite && e.b >= 0) { - above = fast = dyp >= e.b * dxp; - } else { - above = p.x + p.y * e.b > e.c; - if (e.b < 0) { - above = !above; - } - if (!above) { - fast = 1; - } - } - if (!fast) { - var dxs = topsite.x - e.region.l.x; - above = e.b * (dxp * dxp - dyp * dyp) < dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b); - if (e.b < 0) { - above = !above; - } - } - } else { - var yl = e.c - e.a * p.x, t1 = p.y - yl, t2 = p.x - topsite.x, t3 = yl - topsite.y; - above = t1 * t1 > t2 * t2 + t3 * t3; - } - return he.side === "l" ? above : !above; - }, - endPoint: function(edge, side, site) { - edge.ep[side] = site; - if (!edge.ep[d3_geom_voronoiOpposite[side]]) return; - callback(edge); - }, - distance: function(s, t) { - var dx = s.x - t.x, dy = s.y - t.y; - return Math.sqrt(dx * dx + dy * dy); - } - }; - var EventQueue = { - list: [], - insert: function(he, site, offset) { - he.vertex = site; - he.ystar = site.y + offset; - for (var i = 0, list = EventQueue.list, l = list.length; i < l; i++) { - var next = list[i]; - if (he.ystar > next.ystar || he.ystar == next.ystar && site.x > next.vertex.x) { - continue; - } else { - break; - } - } - list.splice(i, 0, he); - }, - del: function(he) { - for (var i = 0, ls = EventQueue.list, l = ls.length; i < l && ls[i] != he; ++i) {} - ls.splice(i, 1); - }, - empty: function() { - return EventQueue.list.length === 0; - }, - nextEvent: function(he) { - for (var i = 0, ls = EventQueue.list, l = ls.length; i < l; ++i) { - if (ls[i] == he) return ls[i + 1]; - } - return null; - }, - min: function() { - var elem = EventQueue.list[0]; - return { - x: elem.vertex.x, - y: elem.ystar - }; - }, - extractMin: function() { - return EventQueue.list.shift(); - } - }; - EdgeList.init(); - Sites.bottomSite = Sites.list.shift(); - var newSite = Sites.list.shift(), newIntStar; - var lbnd, rbnd, llbnd, rrbnd, bisector; - var bot, top, temp, p, v; - var e, pm; - while (true) { - if (!EventQueue.empty()) { - newIntStar = EventQueue.min(); - } - if (newSite && (EventQueue.empty() || newSite.y < newIntStar.y || newSite.y == newIntStar.y && newSite.x < newIntStar.x)) { - lbnd = EdgeList.leftBound(newSite); - rbnd = EdgeList.right(lbnd); - bot = EdgeList.rightRegion(lbnd); - e = Geom.bisect(bot, newSite); - bisector = EdgeList.createHalfEdge(e, "l"); - EdgeList.insert(lbnd, bisector); - p = Geom.intersect(lbnd, bisector); - if (p) { - EventQueue.del(lbnd); - EventQueue.insert(lbnd, p, Geom.distance(p, newSite)); - } - lbnd = bisector; - bisector = EdgeList.createHalfEdge(e, "r"); - EdgeList.insert(lbnd, bisector); - p = Geom.intersect(bisector, rbnd); - if (p) { - EventQueue.insert(bisector, p, Geom.distance(p, newSite)); - } - newSite = Sites.list.shift(); - } else if (!EventQueue.empty()) { - lbnd = EventQueue.extractMin(); - llbnd = EdgeList.left(lbnd); - rbnd = EdgeList.right(lbnd); - rrbnd = EdgeList.right(rbnd); - bot = EdgeList.leftRegion(lbnd); - top = EdgeList.rightRegion(rbnd); - v = lbnd.vertex; - Geom.endPoint(lbnd.edge, lbnd.side, v); - Geom.endPoint(rbnd.edge, rbnd.side, v); - EdgeList.del(lbnd); - EventQueue.del(rbnd); - EdgeList.del(rbnd); - pm = "l"; - if (bot.y > top.y) { - temp = bot; - bot = top; - top = temp; - pm = "r"; - } - e = Geom.bisect(bot, top); - bisector = EdgeList.createHalfEdge(e, pm); - EdgeList.insert(llbnd, bisector); - Geom.endPoint(e, d3_geom_voronoiOpposite[pm], v); - p = Geom.intersect(llbnd, bisector); - if (p) { - EventQueue.del(llbnd); - EventQueue.insert(llbnd, p, Geom.distance(p, bot)); - } - p = Geom.intersect(bisector, rrbnd); - if (p) { - EventQueue.insert(bisector, p, Geom.distance(p, bot)); - } - } else { - break; - } - } - for (lbnd = EdgeList.right(EdgeList.leftEnd); lbnd != EdgeList.rightEnd; lbnd = EdgeList.right(lbnd)) { - callback(lbnd.edge); - } - } - d3.geom.quadtree = function(points, x1, y1, x2, y2) { - var x = d3_svg_lineX, y = d3_svg_lineY, compat; - if (compat = arguments.length) { - x = d3_geom_quadtreeCompatX; - y = d3_geom_quadtreeCompatY; - if (compat === 3) { - y2 = y1; - x2 = x1; - y1 = x1 = 0; - } - return quadtree(points); - } - function quadtree(data) { - var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; - if (x1 != null) { - x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; - } else { - x2_ = y2_ = -(x1_ = y1_ = Infinity); - xs = [], ys = []; - n = data.length; - if (compat) for (i = 0; i < n; ++i) { - d = data[i]; - if (d.x < x1_) x1_ = d.x; - if (d.y < y1_) y1_ = d.y; - if (d.x > x2_) x2_ = d.x; - if (d.y > y2_) y2_ = d.y; - xs.push(d.x); - ys.push(d.y); - } else for (i = 0; i < n; ++i) { - var x_ = +fx(d = data[i], i), y_ = +fy(d, i); - if (x_ < x1_) x1_ = x_; - if (y_ < y1_) y1_ = y_; - if (x_ > x2_) x2_ = x_; - if (y_ > y2_) y2_ = y_; - xs.push(x_); - ys.push(y_); - } - } - var dx = x2_ - x1_, dy = y2_ - y1_; - if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; - function insert(n, d, x, y, x1, y1, x2, y2) { - if (isNaN(x) || isNaN(y)) return; - if (n.leaf) { - var nx = n.x, ny = n.y; - if (nx != null) { - if (Math.abs(nx - x) + Math.abs(ny - y) < .01) { - insertChild(n, d, x, y, x1, y1, x2, y2); - } else { - var nPoint = n.point; - n.x = n.y = n.point = null; - insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } else { - n.x = x, n.y = y, n.point = d; - } - } else { - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } - function insertChild(n, d, x, y, x1, y1, x2, y2) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = x >= sx, bottom = y >= sy, i = (bottom << 1) + right; - n.leaf = false; - n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); - if (right) x1 = sx; else x2 = sx; - if (bottom) y1 = sy; else y2 = sy; - insert(n, d, x, y, x1, y1, x2, y2); - } - var root = d3_geom_quadtreeNode(); - root.add = function(d) { - insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); - }; - root.visit = function(f) { - d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); - }; - i = -1; - if (x1 == null) { - while (++i < n) { - insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); - } - --i; - } else data.forEach(root.add); - xs = ys = data = d = null; - return root; - } - quadtree.x = function(_) { - return arguments.length ? (x = _, quadtree) : x; - }; - quadtree.y = function(_) { - return arguments.length ? (y = _, quadtree) : y; - }; - quadtree.extent = function(_) { - if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], - y2 = +_[1][1]; - return quadtree; - }; - quadtree.size = function(_) { - if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; - return quadtree; - }; - return quadtree; - }; - function d3_geom_quadtreeCompatX(d) { - return d.x; - } - function d3_geom_quadtreeCompatY(d) { - return d.y; - } - function d3_geom_quadtreeNode() { - return { - leaf: true, - nodes: [], - point: null, - x: null, - y: null - }; - } - function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { - if (!f(node, x1, y1, x2, y2)) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; - if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); - if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); - if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); - if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); - } - } - d3.interpolateRgb = d3_interpolateRgb; - function d3_interpolateRgb(a, b) { - a = d3.rgb(a); - b = d3.rgb(b); - var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; - return function(t) { - return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); - }; - } - d3.interpolateObject = d3_interpolateObject; - function d3_interpolateObject(a, b) { - var i = {}, c = {}, k; - for (k in a) { - if (k in b) { - i[k] = d3_interpolate(a[k], b[k]); - } else { - c[k] = a[k]; - } - } - for (k in b) { - if (!(k in a)) { - c[k] = b[k]; - } - } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; - } - d3.interpolateNumber = d3_interpolateNumber; - function d3_interpolateNumber(a, b) { - b -= a = +a; - return function(t) { - return a + b * t; - }; - } - d3.interpolateString = d3_interpolateString; - function d3_interpolateString(a, b) { - var m, i, j, s0 = 0, s1 = 0, s = [], q = [], n, o; - a = a + "", b = b + ""; - d3_interpolate_number.lastIndex = 0; - for (i = 0; m = d3_interpolate_number.exec(b); ++i) { - if (m.index) s.push(b.substring(s0, s1 = m.index)); - q.push({ - i: s.length, - x: m[0] - }); - s.push(null); - s0 = d3_interpolate_number.lastIndex; - } - if (s0 < b.length) s.push(b.substring(s0)); - for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { - o = q[i]; - if (o.x == m[0]) { - if (o.i) { - if (s[o.i + 1] == null) { - s[o.i - 1] += o.x; - s.splice(o.i, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } else { - s[o.i - 1] += o.x + s[o.i + 1]; - s.splice(o.i, 2); - for (j = i + 1; j < n; ++j) q[j].i -= 2; - } - } else { - if (s[o.i + 1] == null) { - s[o.i] = o.x; - } else { - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } - } - q.splice(i, 1); - n--; - i--; - } else { - o.x = d3_interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); - } - } - while (i < n) { - o = q.pop(); - if (s[o.i + 1] == null) { - s[o.i] = o.x; - } else { - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - } - n--; - } - if (s.length === 1) { - return s[0] == null ? (o = q[0].x, function(t) { - return o(t) + ""; - }) : function() { - return b; - }; - } - return function(t) { - for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; - d3.interpolate = d3_interpolate; - function d3_interpolate(a, b) { - var i = d3.interpolators.length, f; - while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; - return f; - } - d3.interpolators = [ function(a, b) { - var t = typeof b; - return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_Color ? d3_interpolateRgb : t === "object" ? Array.isArray(b) ? d3_interpolateArray : d3_interpolateObject : d3_interpolateNumber)(a, b); - } ]; - d3.interpolateArray = d3_interpolateArray; - function d3_interpolateArray(a, b) { - var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; - for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); - for (;i < na; ++i) c[i] = a[i]; - for (;i < nb; ++i) c[i] = b[i]; - return function(t) { - for (i = 0; i < n0; ++i) c[i] = x[i](t); - return c; - }; - } - var d3_ease_default = function() { - return d3_identity; - }; - var d3_ease = d3.map({ - linear: d3_ease_default, - poly: d3_ease_poly, - quad: function() { - return d3_ease_quad; - }, - cubic: function() { - return d3_ease_cubic; - }, - sin: function() { - return d3_ease_sin; - }, - exp: function() { - return d3_ease_exp; - }, - circle: function() { - return d3_ease_circle; - }, - elastic: d3_ease_elastic, - back: d3_ease_back, - bounce: function() { - return d3_ease_bounce; - } - }); - var d3_ease_mode = d3.map({ - "in": d3_identity, - out: d3_ease_reverse, - "in-out": d3_ease_reflect, - "out-in": function(f) { - return d3_ease_reflect(d3_ease_reverse(f)); - } - }); - d3.ease = function(name) { - var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in"; - t = d3_ease.get(t) || d3_ease_default; - m = d3_ease_mode.get(m) || d3_identity; - return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1)))); - }; - function d3_ease_clamp(f) { - return function(t) { - return t <= 0 ? 0 : t >= 1 ? 1 : f(t); - }; - } - function d3_ease_reverse(f) { - return function(t) { - return 1 - f(1 - t); - }; - } - function d3_ease_reflect(f) { - return function(t) { - return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); - }; - } - function d3_ease_quad(t) { - return t * t; - } - function d3_ease_cubic(t) { - return t * t * t; - } - function d3_ease_cubicInOut(t) { - if (t <= 0) return 0; - if (t >= 1) return 1; - var t2 = t * t, t3 = t2 * t; - return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); - } - function d3_ease_poly(e) { - return function(t) { - return Math.pow(t, e); - }; - } - function d3_ease_sin(t) { - return 1 - Math.cos(t * π / 2); - } - function d3_ease_exp(t) { - return Math.pow(2, 10 * (t - 1)); - } - function d3_ease_circle(t) { - return 1 - Math.sqrt(1 - t * t); - } - function d3_ease_elastic(a, p) { - var s; - if (arguments.length < 2) p = .45; - if (arguments.length) s = p / (2 * π) * Math.asin(1 / a); else a = 1, s = p / 4; - return function(t) { - return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * π / p); - }; - } - function d3_ease_back(s) { - if (!s) s = 1.70158; - return function(t) { - return t * t * ((s + 1) * t - s); - }; - } - function d3_ease_bounce(t) { - return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; - } - d3.interpolateHcl = d3_interpolateHcl; - function d3_interpolateHcl(a, b) { - a = d3.hcl(a); - b = d3.hcl(b); - var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; - if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; - }; - } - d3.interpolateHsl = d3_interpolateHsl; - function d3_interpolateHsl(a, b) { - a = d3.hsl(a); - b = d3.hsl(b); - var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; - if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; - }; - } - d3.interpolateLab = d3_interpolateLab; - function d3_interpolateLab(a, b) { - a = d3.lab(a); - b = d3.lab(b); - var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; - return function(t) { - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; - }; - } - d3.interpolateRound = d3_interpolateRound; - function d3_interpolateRound(a, b) { - b -= a; - return function(t) { - return Math.round(a + b * t); - }; - } - d3.transform = function(string) { - var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); - return (d3.transform = function(string) { - if (string != null) { - g.setAttribute("transform", string); - var t = g.transform.baseVal.consolidate(); - } - return new d3_transform(t ? t.matrix : d3_transformIdentity); - })(string); - }; - function d3_transform(m) { - var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; - if (r0[0] * r1[1] < r1[0] * r0[1]) { - r0[0] *= -1; - r0[1] *= -1; - kx *= -1; - kz *= -1; - } - this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; - this.translate = [ m.e, m.f ]; - this.scale = [ kx, ky ]; - this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; - } - d3_transform.prototype.toString = function() { - return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; - }; - function d3_transformDot(a, b) { - return a[0] * b[0] + a[1] * b[1]; - } - function d3_transformNormalize(a) { - var k = Math.sqrt(d3_transformDot(a, a)); - if (k) { - a[0] /= k; - a[1] /= k; - } - return k; - } - function d3_transformCombine(a, b, k) { - a[0] += k * b[0]; - a[1] += k * b[1]; - return a; - } - var d3_transformIdentity = { - a: 1, - b: 0, - c: 0, - d: 1, - e: 0, - f: 0 - }; - d3.interpolateTransform = d3_interpolateTransform; - function d3_interpolateTransform(a, b) { - var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; - if (ta[0] != tb[0] || ta[1] != tb[1]) { - s.push("translate(", null, ",", null, ")"); - q.push({ - i: 1, - x: d3_interpolateNumber(ta[0], tb[0]) - }, { - i: 3, - x: d3_interpolateNumber(ta[1], tb[1]) - }); - } else if (tb[0] || tb[1]) { - s.push("translate(" + tb + ")"); - } else { - s.push(""); - } - if (ra != rb) { - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; - q.push({ - i: s.push(s.pop() + "rotate(", null, ")") - 2, - x: d3_interpolateNumber(ra, rb) - }); - } else if (rb) { - s.push(s.pop() + "rotate(" + rb + ")"); - } - if (wa != wb) { - q.push({ - i: s.push(s.pop() + "skewX(", null, ")") - 2, - x: d3_interpolateNumber(wa, wb) - }); - } else if (wb) { - s.push(s.pop() + "skewX(" + wb + ")"); - } - if (ka[0] != kb[0] || ka[1] != kb[1]) { - n = s.push(s.pop() + "scale(", null, ",", null, ")"); - q.push({ - i: n - 4, - x: d3_interpolateNumber(ka[0], kb[0]) - }, { - i: n - 2, - x: d3_interpolateNumber(ka[1], kb[1]) - }); - } else if (kb[0] != 1 || kb[1] != 1) { - s.push(s.pop() + "scale(" + kb + ")"); - } - n = q.length; - return function(t) { - var i = -1, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - function d3_uninterpolateNumber(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { - return (x - a) * b; - }; - } - function d3_uninterpolateClamp(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { - return Math.max(0, Math.min(1, (x - a) * b)); - }; - } - d3.layout = {}; - d3.layout.bundle = function() { - return function(links) { - var paths = [], i = -1, n = links.length; - while (++i < n) paths.push(d3_layout_bundlePath(links[i])); - return paths; - }; - }; - function d3_layout_bundlePath(link) { - var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; - while (start !== lca) { - start = start.parent; - points.push(start); - } - var k = points.length; - while (end !== lca) { - points.splice(k, 0, end); - end = end.parent; - } - return points; - } - function d3_layout_bundleAncestors(node) { - var ancestors = [], parent = node.parent; - while (parent != null) { - ancestors.push(node); - node = parent; - parent = parent.parent; - } - ancestors.push(node); - return ancestors; - } - function d3_layout_bundleLeastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; - while (aNode === bNode) { - sharedNode = aNode; - aNode = aNodes.pop(); - bNode = bNodes.pop(); - } - return sharedNode; - } - d3.layout.chord = function() { - var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; - function relayout() { - var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; - chords = []; - groups = []; - k = 0, i = -1; - while (++i < n) { - x = 0, j = -1; - while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(d3.range(n)); - k += x; - } - if (sortGroups) { - groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); - } - if (sortSubgroups) { - subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); - } - k = (2 * π - padding * n) / k; - x = 0, i = -1; - while (++i < n) { - x0 = x, j = -1; - while (++j < n) { - var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; - subgroups[di + "-" + dj] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: (x - x0) / k - }; - x += padding; - } - i = -1; - while (++i < n) { - j = i - 1; - while (++j < n) { - var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; - if (source.value || target.value) { - chords.push(source.value < target.value ? { - source: target, - target: source - } : { - source: source, - target: target - }); - } - } - } - if (sortChords) resort(); - } - function resort() { - chords.sort(function(a, b) { - return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); - }); - } - chord.matrix = function(x) { - if (!arguments.length) return matrix; - n = (matrix = x) && matrix.length; - chords = groups = null; - return chord; - }; - chord.padding = function(x) { - if (!arguments.length) return padding; - padding = x; - chords = groups = null; - return chord; - }; - chord.sortGroups = function(x) { - if (!arguments.length) return sortGroups; - sortGroups = x; - chords = groups = null; - return chord; - }; - chord.sortSubgroups = function(x) { - if (!arguments.length) return sortSubgroups; - sortSubgroups = x; - chords = null; - return chord; - }; - chord.sortChords = function(x) { - if (!arguments.length) return sortChords; - sortChords = x; - if (chords) resort(); - return chord; - }; - chord.chords = function() { - if (!chords) relayout(); - return chords; - }; - chord.groups = function() { - if (!groups) relayout(); - return groups; - }; - return chord; - }; - d3.layout.force = function() { - var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, gravity = .1, theta = .8, nodes = [], links = [], distances, strengths, charges; - function repulse(node) { - return function(quad, x1, _, x2) { - if (quad.point !== node) { - var dx = quad.cx - node.x, dy = quad.cy - node.y, dn = 1 / Math.sqrt(dx * dx + dy * dy); - if ((x2 - x1) * dn < theta) { - var k = quad.charge * dn * dn; - node.px -= dx * k; - node.py -= dy * k; - return true; - } - if (quad.point && isFinite(dn)) { - var k = quad.pointCharge * dn * dn; - node.px -= dx * k; - node.py -= dy * k; - } - } - return !quad.charge; - }; - } - force.tick = function() { - if ((alpha *= .99) < .005) { - event.end({ - type: "end", - alpha: alpha = 0 - }); - return true; - } - var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; - for (i = 0; i < m; ++i) { - o = links[i]; - s = o.source; - t = o.target; - x = t.x - s.x; - y = t.y - s.y; - if (l = x * x + y * y) { - l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; - x *= l; - y *= l; - t.x -= x * (k = s.weight / (t.weight + s.weight)); - t.y -= y * k; - s.x += x * (k = 1 - k); - s.y += y * k; - } - } - if (k = alpha * gravity) { - x = size[0] / 2; - y = size[1] / 2; - i = -1; - if (k) while (++i < n) { - o = nodes[i]; - o.x += (x - o.x) * k; - o.y += (y - o.y) * k; - } - } - if (charge) { - d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); - i = -1; - while (++i < n) { - if (!(o = nodes[i]).fixed) { - q.visit(repulse(o)); - } - } - } - i = -1; - while (++i < n) { - o = nodes[i]; - if (o.fixed) { - o.x = o.px; - o.y = o.py; - } else { - o.x -= (o.px - (o.px = o.x)) * friction; - o.y -= (o.py - (o.py = o.y)) * friction; - } - } - event.tick({ - type: "tick", - alpha: alpha - }); - }; - force.nodes = function(x) { - if (!arguments.length) return nodes; - nodes = x; - return force; - }; - force.links = function(x) { - if (!arguments.length) return links; - links = x; - return force; - }; - force.size = function(x) { - if (!arguments.length) return size; - size = x; - return force; - }; - force.linkDistance = function(x) { - if (!arguments.length) return linkDistance; - linkDistance = typeof x === "function" ? x : +x; - return force; - }; - force.distance = force.linkDistance; - force.linkStrength = function(x) { - if (!arguments.length) return linkStrength; - linkStrength = typeof x === "function" ? x : +x; - return force; - }; - force.friction = function(x) { - if (!arguments.length) return friction; - friction = +x; - return force; - }; - force.charge = function(x) { - if (!arguments.length) return charge; - charge = typeof x === "function" ? x : +x; - return force; - }; - force.gravity = function(x) { - if (!arguments.length) return gravity; - gravity = +x; - return force; - }; - force.theta = function(x) { - if (!arguments.length) return theta; - theta = +x; - return force; - }; - force.alpha = function(x) { - if (!arguments.length) return alpha; - x = +x; - if (alpha) { - if (x > 0) alpha = x; else alpha = 0; - } else if (x > 0) { - event.start({ - type: "start", - alpha: alpha = x - }); - d3.timer(force.tick); - } - return force; - }; - force.start = function() { - var i, j, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; - for (i = 0; i < n; ++i) { - (o = nodes[i]).index = i; - o.weight = 0; - } - for (i = 0; i < m; ++i) { - o = links[i]; - if (typeof o.source == "number") o.source = nodes[o.source]; - if (typeof o.target == "number") o.target = nodes[o.target]; - ++o.source.weight; - ++o.target.weight; - } - for (i = 0; i < n; ++i) { - o = nodes[i]; - if (isNaN(o.x)) o.x = position("x", w); - if (isNaN(o.y)) o.y = position("y", h); - if (isNaN(o.px)) o.px = o.x; - if (isNaN(o.py)) o.py = o.y; - } - distances = []; - if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; - strengths = []; - if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; - charges = []; - if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; - function position(dimension, size) { - var neighbors = neighbor(i), j = -1, m = neighbors.length, x; - while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x; - return Math.random() * size; - } - function neighbor() { - if (!neighbors) { - neighbors = []; - for (j = 0; j < n; ++j) { - neighbors[j] = []; - } - for (j = 0; j < m; ++j) { - var o = links[j]; - neighbors[o.source.index].push(o.target); - neighbors[o.target.index].push(o.source); - } - } - return neighbors[i]; - } - return force.resume(); - }; - force.resume = function() { - return force.alpha(.1); - }; - force.stop = function() { - return force.alpha(0); - }; - force.drag = function() { - if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); - if (!arguments.length) return drag; - this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); - }; - function dragmove(d) { - d.px = d3.event.x, d.py = d3.event.y; - force.resume(); - } - return d3.rebind(force, event, "on"); - }; - function d3_layout_forceDragstart(d) { - d.fixed |= 2; - } - function d3_layout_forceDragend(d) { - d.fixed &= ~6; - } - function d3_layout_forceMouseover(d) { - d.fixed |= 4; - d.px = d.x, d.py = d.y; - } - function d3_layout_forceMouseout(d) { - d.fixed &= ~4; - } - function d3_layout_forceAccumulate(quad, alpha, charges) { - var cx = 0, cy = 0; - quad.charge = 0; - if (!quad.leaf) { - var nodes = quad.nodes, n = nodes.length, i = -1, c; - while (++i < n) { - c = nodes[i]; - if (c == null) continue; - d3_layout_forceAccumulate(c, alpha, charges); - quad.charge += c.charge; - cx += c.charge * c.cx; - cy += c.charge * c.cy; - } - } - if (quad.point) { - if (!quad.leaf) { - quad.point.x += Math.random() - .5; - quad.point.y += Math.random() - .5; - } - var k = alpha * charges[quad.point.index]; - quad.charge += quad.pointCharge = k; - cx += k * quad.point.x; - cy += k * quad.point.y; - } - quad.cx = cx / quad.charge; - quad.cy = cy / quad.charge; - } - var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1; - d3.layout.hierarchy = function() { - var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; - function recurse(node, depth, nodes) { - var childs = children.call(hierarchy, node, depth); - node.depth = depth; - nodes.push(node); - if (childs && (n = childs.length)) { - var i = -1, n, c = node.children = [], v = 0, j = depth + 1, d; - while (++i < n) { - d = recurse(childs[i], j, nodes); - d.parent = node; - c.push(d); - v += d.value; - } - if (sort) c.sort(sort); - if (value) node.value = v; - } else if (value) { - node.value = +value.call(hierarchy, node, depth) || 0; - } - return node; - } - function revalue(node, depth) { - var children = node.children, v = 0; - if (children && (n = children.length)) { - var i = -1, n, j = depth + 1; - while (++i < n) v += revalue(children[i], j); - } else if (value) { - v = +value.call(hierarchy, node, depth) || 0; - } - if (value) node.value = v; - return v; - } - function hierarchy(d) { - var nodes = []; - recurse(d, 0, nodes); - return nodes; - } - hierarchy.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return hierarchy; - }; - hierarchy.children = function(x) { - if (!arguments.length) return children; - children = x; - return hierarchy; - }; - hierarchy.value = function(x) { - if (!arguments.length) return value; - value = x; - return hierarchy; - }; - hierarchy.revalue = function(root) { - revalue(root, 0); - return root; - }; - return hierarchy; - }; - function d3_layout_hierarchyRebind(object, hierarchy) { - d3.rebind(object, hierarchy, "sort", "children", "value"); - object.nodes = object; - object.links = d3_layout_hierarchyLinks; - return object; - } - function d3_layout_hierarchyChildren(d) { - return d.children; - } - function d3_layout_hierarchyValue(d) { - return d.value; - } - function d3_layout_hierarchySort(a, b) { - return b.value - a.value; - } - function d3_layout_hierarchyLinks(nodes) { - return d3.merge(nodes.map(function(parent) { - return (parent.children || []).map(function(child) { - return { - source: parent, - target: child - }; - }); - })); - } - d3.layout.partition = function() { - var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; - function position(node, x, dx, dy) { - var children = node.children; - node.x = x; - node.y = node.depth * dy; - node.dx = dx; - node.dy = dy; - if (children && (n = children.length)) { - var i = -1, n, c, d; - dx = node.value ? dx / node.value : 0; - while (++i < n) { - position(c = children[i], x, d = c.value * dx, dy); - x += d; - } - } - } - function depth(node) { - var children = node.children, d = 0; - if (children && (n = children.length)) { - var i = -1, n; - while (++i < n) d = Math.max(d, depth(children[i])); - } - return 1 + d; - } - function partition(d, i) { - var nodes = hierarchy.call(this, d, i); - position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); - return nodes; - } - partition.size = function(x) { - if (!arguments.length) return size; - size = x; - return partition; - }; - return d3_layout_hierarchyRebind(partition, hierarchy); - }; - d3.layout.pie = function() { - var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = 2 * π; - function pie(data) { - var values = data.map(function(d, i) { - return +value.call(pie, d, i); - }); - var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle); - var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a) / d3.sum(values); - var index = d3.range(data.length); - if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { - return values[j] - values[i]; - } : function(i, j) { - return sort(data[i], data[j]); - }); - var arcs = []; - index.forEach(function(i) { - var d; - arcs[i] = { - data: data[i], - value: d = values[i], - startAngle: a, - endAngle: a += d * k - }; - }); - return arcs; - } - pie.value = function(x) { - if (!arguments.length) return value; - value = x; - return pie; - }; - pie.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return pie; - }; - pie.startAngle = function(x) { - if (!arguments.length) return startAngle; - startAngle = x; - return pie; - }; - pie.endAngle = function(x) { - if (!arguments.length) return endAngle; - endAngle = x; - return pie; - }; - return pie; - }; - var d3_layout_pieSortByValue = {}; - d3.layout.stack = function() { - var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; - function stack(data, index) { - var series = data.map(function(d, i) { - return values.call(stack, d, i); - }); - var points = series.map(function(d) { - return d.map(function(v, i) { - return [ x.call(stack, v, i), y.call(stack, v, i) ]; - }); - }); - var orders = order.call(stack, points, index); - series = d3.permute(series, orders); - points = d3.permute(points, orders); - var offsets = offset.call(stack, points, index); - var n = series.length, m = series[0].length, i, j, o; - for (j = 0; j < m; ++j) { - out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); - for (i = 1; i < n; ++i) { - out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); - } - } - return data; - } - stack.values = function(x) { - if (!arguments.length) return values; - values = x; - return stack; - }; - stack.order = function(x) { - if (!arguments.length) return order; - order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; - return stack; - }; - stack.offset = function(x) { - if (!arguments.length) return offset; - offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; - return stack; - }; - stack.x = function(z) { - if (!arguments.length) return x; - x = z; - return stack; - }; - stack.y = function(z) { - if (!arguments.length) return y; - y = z; - return stack; - }; - stack.out = function(z) { - if (!arguments.length) return out; - out = z; - return stack; - }; - return stack; - }; - function d3_layout_stackX(d) { - return d.x; - } - function d3_layout_stackY(d) { - return d.y; - } - function d3_layout_stackOut(d, y0, y) { - d.y0 = y0; - d.y = y; - } - var d3_layout_stackOrders = d3.map({ - "inside-out": function(data) { - var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { - return max[a] - max[b]; - }), top = 0, bottom = 0, tops = [], bottoms = []; - for (i = 0; i < n; ++i) { - j = index[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } - } - return bottoms.reverse().concat(tops); - }, - reverse: function(data) { - return d3.range(data.length).reverse(); - }, - "default": d3_layout_stackOrderDefault - }); - var d3_layout_stackOffsets = d3.map({ - silhouette: function(data) { - var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o > max) max = o; - sums.push(o); - } - for (j = 0; j < m; ++j) { - y0[j] = (max - sums[j]) / 2; - } - return y0; - }, - wiggle: function(data) { - var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; - y0[0] = o = o0 = 0; - for (j = 1; j < m; ++j) { - for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; - for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { - for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { - s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; - } - s2 += s3 * data[i][j][1]; - } - y0[j] = o -= s1 ? s2 / s1 * dx : 0; - if (o < o0) o0 = o; - } - for (j = 0; j < m; ++j) y0[j] -= o0; - return y0; - }, - expand: function(data) { - var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }, - zero: d3_layout_stackOffsetZero - }); - function d3_layout_stackOrderDefault(data) { - return d3.range(data.length); - } - function d3_layout_stackOffsetZero(data) { - var j = -1, m = data[0].length, y0 = []; - while (++j < m) y0[j] = 0; - return y0; - } - function d3_layout_stackMaxIndex(array) { - var i = 1, j = 0, v = array[0][1], k, n = array.length; - for (;i < n; ++i) { - if ((k = array[i][1]) > v) { - j = i; - v = k; - } - } - return j; - } - function d3_layout_stackReduceSum(d) { - return d.reduce(d3_layout_stackSum, 0); - } - function d3_layout_stackSum(p, d) { - return p + d[1]; - } - d3.layout.histogram = function() { - var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; - function histogram(data, i) { - var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; - while (++i < m) { - bin = bins[i] = []; - bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); - bin.y = 0; - } - if (m > 0) { - i = -1; - while (++i < n) { - x = values[i]; - if (x >= range[0] && x <= range[1]) { - bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; - bin.y += k; - bin.push(data[i]); - } - } - } - return bins; - } - histogram.value = function(x) { - if (!arguments.length) return valuer; - valuer = x; - return histogram; - }; - histogram.range = function(x) { - if (!arguments.length) return ranger; - ranger = d3_functor(x); - return histogram; - }; - histogram.bins = function(x) { - if (!arguments.length) return binner; - binner = typeof x === "number" ? function(range) { - return d3_layout_histogramBinFixed(range, x); - } : d3_functor(x); - return histogram; - }; - histogram.frequency = function(x) { - if (!arguments.length) return frequency; - frequency = !!x; - return histogram; - }; - return histogram; - }; - function d3_layout_histogramBinSturges(range, values) { - return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); - } - function d3_layout_histogramBinFixed(range, n) { - var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; - while (++x <= n) f[x] = m * x + b; - return f; - } - function d3_layout_histogramRange(values) { - return [ d3.min(values), d3.max(values) ]; - } - d3.layout.tree = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function tree(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0]; - function firstWalk(node, previousSibling) { - var children = node.children, layout = node._tree; - if (children && (n = children.length)) { - var n, firstChild = children[0], previousChild, ancestor = firstChild, child, i = -1; - while (++i < n) { - child = children[i]; - firstWalk(child, previousChild); - ancestor = apportion(child, previousChild, ancestor); - previousChild = child; - } - d3_layout_treeShift(node); - var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - layout.mod = layout.prelim - midpoint; - } else { - layout.prelim = midpoint; - } - } else { - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - } - } - } - function secondWalk(node, x) { - node.x = node._tree.prelim + x; - var children = node.children; - if (children && (n = children.length)) { - var i = -1, n; - x += node._tree.mod; - while (++i < n) { - secondWalk(children[i], x); - } - } - } - function apportion(node, previousSibling, ancestor) { - if (previousSibling) { - var vip = node, vop = node, vim = previousSibling, vom = node.parent.children[0], sip = vip._tree.mod, sop = vop._tree.mod, sim = vim._tree.mod, som = vom._tree.mod, shift; - while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { - vom = d3_layout_treeLeft(vom); - vop = d3_layout_treeRight(vop); - vop._tree.ancestor = node; - shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); - if (shift > 0) { - d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); - sip += shift; - sop += shift; - } - sim += vim._tree.mod; - sip += vip._tree.mod; - som += vom._tree.mod; - sop += vop._tree.mod; - } - if (vim && !d3_layout_treeRight(vop)) { - vop._tree.thread = vim; - vop._tree.mod += sim - sop; - } - if (vip && !d3_layout_treeLeft(vom)) { - vom._tree.thread = vip; - vom._tree.mod += sip - som; - ancestor = node; - } - } - return ancestor; - } - d3_layout_treeVisitAfter(root, function(node, previousSibling) { - node._tree = { - ancestor: node, - prelim: 0, - mod: 0, - change: 0, - shift: 0, - number: previousSibling ? previousSibling._tree.number + 1 : 0 - }; - }); - firstWalk(root); - secondWalk(root, -root._tree.prelim); - var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), right = d3_layout_treeSearch(root, d3_layout_treeRightmost), deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2, y1 = deep.depth || 1; - d3_layout_treeVisitAfter(root, nodeSize ? function(node) { - node.x *= size[0]; - node.y = node.depth * size[1]; - delete node._tree; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = node.depth / y1 * size[1]; - delete node._tree; - }); - return nodes; - } - tree.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return tree; - }; - tree.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return tree; - }; - tree.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return tree; - }; - return d3_layout_hierarchyRebind(tree, hierarchy); - }; - function d3_layout_treeSeparation(a, b) { - return a.parent == b.parent ? 1 : 2; - } - function d3_layout_treeLeft(node) { - var children = node.children; - return children && children.length ? children[0] : node._tree.thread; - } - function d3_layout_treeRight(node) { - var children = node.children, n; - return children && (n = children.length) ? children[n - 1] : node._tree.thread; - } - function d3_layout_treeSearch(node, compare) { - var children = node.children; - if (children && (n = children.length)) { - var child, n, i = -1; - while (++i < n) { - if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { - node = child; - } - } - } - return node; - } - function d3_layout_treeRightmost(a, b) { - return a.x - b.x; - } - function d3_layout_treeLeftmost(a, b) { - return b.x - a.x; - } - function d3_layout_treeDeepest(a, b) { - return a.depth - b.depth; - } - function d3_layout_treeVisitAfter(node, callback) { - function visit(node, previousSibling) { - var children = node.children; - if (children && (n = children.length)) { - var child, previousChild = null, i = -1, n; - while (++i < n) { - child = children[i]; - visit(child, previousChild); - previousChild = child; - } - } - callback(node, previousSibling); - } - visit(node, null); - } - function d3_layout_treeShift(node) { - var shift = 0, change = 0, children = node.children, i = children.length, child; - while (--i >= 0) { - child = children[i]._tree; - child.prelim += shift; - child.mod += shift; - shift += child.shift + (change += child.change); - } - } - function d3_layout_treeMove(ancestor, node, shift) { - ancestor = ancestor._tree; - node = node._tree; - var change = shift / (node.number - ancestor.number); - ancestor.change += change; - node.change -= change; - node.shift += shift; - node.prelim += shift; - node.mod += shift; - } - function d3_layout_treeAncestor(vim, node, ancestor) { - return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor; - } - d3.layout.pack = function() { - var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; - function pack(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { - return radius; - }; - root.x = root.y = 0; - d3_layout_treeVisitAfter(root, function(d) { - d.r = +r(d.value); - }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - if (padding) { - var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; - d3_layout_treeVisitAfter(root, function(d) { - d.r += dr; - }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - d3_layout_treeVisitAfter(root, function(d) { - d.r -= dr; - }); - } - d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); - return nodes; - } - pack.size = function(_) { - if (!arguments.length) return size; - size = _; - return pack; - }; - pack.radius = function(_) { - if (!arguments.length) return radius; - radius = _ == null || typeof _ === "function" ? _ : +_; - return pack; - }; - pack.padding = function(_) { - if (!arguments.length) return padding; - padding = +_; - return pack; - }; - return d3_layout_hierarchyRebind(pack, hierarchy); - }; - function d3_layout_packSort(a, b) { - return a.value - b.value; - } - function d3_layout_packInsert(a, b) { - var c = a._pack_next; - a._pack_next = b; - b._pack_prev = a; - b._pack_next = c; - c._pack_prev = b; - } - function d3_layout_packSplice(a, b) { - a._pack_next = b; - b._pack_prev = a; - } - function d3_layout_packIntersects(a, b) { - var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; - return .999 * dr * dr > dx * dx + dy * dy; - } - function d3_layout_packSiblings(node) { - if (!(nodes = node.children) || !(n = nodes.length)) return; - var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; - function bound(node) { - xMin = Math.min(node.x - node.r, xMin); - xMax = Math.max(node.x + node.r, xMax); - yMin = Math.min(node.y - node.r, yMin); - yMax = Math.max(node.y + node.r, yMax); - } - nodes.forEach(d3_layout_packLink); - a = nodes[0]; - a.x = -a.r; - a.y = 0; - bound(a); - if (n > 1) { - b = nodes[1]; - b.x = b.r; - b.y = 0; - bound(b); - if (n > 2) { - c = nodes[2]; - d3_layout_packPlace(a, b, c); - bound(c); - d3_layout_packInsert(a, c); - a._pack_prev = c; - d3_layout_packInsert(c, b); - b = a._pack_next; - for (i = 3; i < n; i++) { - d3_layout_packPlace(a, b, c = nodes[i]); - var isect = 0, s1 = 1, s2 = 1; - for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { - if (d3_layout_packIntersects(j, c)) { - isect = 1; - break; - } - } - if (isect == 1) { - for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { - if (d3_layout_packIntersects(k, c)) { - break; - } - } - } - if (isect) { - if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); - i--; - } else { - d3_layout_packInsert(a, c); - b = c; - bound(c); - } - } - } - } - var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; - for (i = 0; i < n; i++) { - c = nodes[i]; - c.x -= cx; - c.y -= cy; - cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); - } - node.r = cr; - nodes.forEach(d3_layout_packUnlink); - } - function d3_layout_packLink(node) { - node._pack_next = node._pack_prev = node; - } - function d3_layout_packUnlink(node) { - delete node._pack_next; - delete node._pack_prev; - } - function d3_layout_packTransform(node, x, y, k) { - var children = node.children; - node.x = x += k * node.x; - node.y = y += k * node.y; - node.r *= k; - if (children) { - var i = -1, n = children.length; - while (++i < n) d3_layout_packTransform(children[i], x, y, k); - } - } - function d3_layout_packPlace(a, b, c) { - var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; - if (db && (dx || dy)) { - var da = b.r + c.r, dc = dx * dx + dy * dy; - da *= da; - db *= db; - var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); - c.x = a.x + x * dx + y * dy; - c.y = a.y + x * dy - y * dx; - } else { - c.x = a.x + db; - c.y = a.y; - } - } - d3.layout.cluster = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function cluster(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; - d3_layout_treeVisitAfter(root, function(node) { - var children = node.children; - if (children && children.length) { - node.x = d3_layout_clusterX(children); - node.y = d3_layout_clusterY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; - } - }); - var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; - d3_layout_treeVisitAfter(root, nodeSize ? function(node) { - node.x = (node.x - root.x) * size[0]; - node.y = (root.y - node.y) * size[1]; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; - }); - return nodes; - } - cluster.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return cluster; - }; - cluster.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return cluster; - }; - cluster.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return cluster; - }; - return d3_layout_hierarchyRebind(cluster, hierarchy); - }; - function d3_layout_clusterY(children) { - return 1 + d3.max(children, function(child) { - return child.y; - }); - } - function d3_layout_clusterX(children) { - return children.reduce(function(x, child) { - return x + child.x; - }, 0) / children.length; - } - function d3_layout_clusterLeft(node) { - var children = node.children; - return children && children.length ? d3_layout_clusterLeft(children[0]) : node; - } - function d3_layout_clusterRight(node) { - var children = node.children, n; - return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; - } - d3.layout.treemap = function() { - var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); - function scale(children, k) { - var i = -1, n = children.length, child, area; - while (++i < n) { - area = (child = children[i]).value * (k < 0 ? 0 : k); - child.area = isNaN(area) || area <= 0 ? 0 : area; - } - } - function squarify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while ((n = remaining.length) > 0) { - row.push(child = remaining[n - 1]); - row.area += child.area; - if (mode !== "squarify" || (score = worst(row, u)) <= best) { - remaining.pop(); - best = score; - } else { - row.area -= row.pop().area; - position(row, u, rect, false); - u = Math.min(rect.dx, rect.dy); - row.length = row.area = 0; - best = Infinity; - } - } - if (row.length) { - position(row, u, rect, true); - row.length = row.area = 0; - } - children.forEach(squarify); - } - } - function stickify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), remaining = children.slice(), child, row = []; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while (child = remaining.pop()) { - row.push(child); - row.area += child.area; - if (child.z != null) { - position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); - row.length = row.area = 0; - } - } - children.forEach(stickify); - } - } - function worst(row, u) { - var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; - while (++i < n) { - if (!(r = row[i].area)) continue; - if (r < rmin) rmin = r; - if (r > rmax) rmax = r; - } - s *= s; - u *= u; - return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; - } - function position(row, u, rect, flush) { - var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; - if (u == rect.dx) { - if (flush || v > rect.dy) v = rect.dy; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dy = v; - x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); - } - o.z = true; - o.dx += rect.x + rect.dx - x; - rect.y += v; - rect.dy -= v; - } else { - if (flush || v > rect.dx) v = rect.dx; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dx = v; - y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); - } - o.z = false; - o.dy += rect.y + rect.dy - y; - rect.x += v; - rect.dx -= v; - } - } - function treemap(d) { - var nodes = stickies || hierarchy(d), root = nodes[0]; - root.x = 0; - root.y = 0; - root.dx = size[0]; - root.dy = size[1]; - if (stickies) hierarchy.revalue(root); - scale([ root ], root.dx * root.dy / root.value); - (stickies ? stickify : squarify)(root); - if (sticky) stickies = nodes; - return nodes; - } - treemap.size = function(x) { - if (!arguments.length) return size; - size = x; - return treemap; - }; - treemap.padding = function(x) { - if (!arguments.length) return padding; - function padFunction(node) { - var p = x.call(treemap, node, node.depth); - return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); - } - function padConstant(node) { - return d3_layout_treemapPad(node, x); - } - var type; - pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], - padConstant) : padConstant; - return treemap; - }; - treemap.round = function(x) { - if (!arguments.length) return round != Number; - round = x ? Math.round : Number; - return treemap; - }; - treemap.sticky = function(x) { - if (!arguments.length) return sticky; - sticky = x; - stickies = null; - return treemap; - }; - treemap.ratio = function(x) { - if (!arguments.length) return ratio; - ratio = x; - return treemap; - }; - treemap.mode = function(x) { - if (!arguments.length) return mode; - mode = x + ""; - return treemap; - }; - return d3_layout_hierarchyRebind(treemap, hierarchy); - }; - function d3_layout_treemapPadNull(node) { - return { - x: node.x, - y: node.y, - dx: node.dx, - dy: node.dy - }; - } - function d3_layout_treemapPad(node, padding) { - var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; - if (dx < 0) { - x += dx / 2; - dx = 0; - } - if (dy < 0) { - y += dy / 2; - dy = 0; - } - return { - x: x, - y: y, - dx: dx, - dy: dy - }; - } - d3.random = { - normal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - return function() { - var x, y, r; - do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); - return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); - }; - }, - logNormal: function() { - var random = d3.random.normal.apply(d3, arguments); - return function() { - return Math.exp(random()); - }; - }, - irwinHall: function(m) { - return function() { - for (var s = 0, j = 0; j < m; j++) s += Math.random(); - return s / m; - }; - } - }; - d3.scale = {}; - function d3_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; - } - function d3_scaleRange(scale) { - return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); - } - function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { - var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); - return function(x) { - return i(u(x)); - }; - } - function d3_scale_nice(domain, nice) { - var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; - if (x1 < x0) { - dx = i0, i0 = i1, i1 = dx; - dx = x0, x0 = x1, x1 = dx; - } - domain[i0] = nice.floor(x0); - domain[i1] = nice.ceil(x1); - return domain; - } - function d3_scale_niceStep(step) { - return step ? { - floor: function(x) { - return Math.floor(x / step) * step; - }, - ceil: function(x) { - return Math.ceil(x / step) * step; - } - } : d3_scale_niceIdentity; - } - var d3_scale_niceIdentity = { - floor: d3_identity, - ceil: d3_identity - }; - function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { - var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; - if (domain[k] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - while (++j <= k) { - u.push(uninterpolate(domain[j - 1], domain[j])); - i.push(interpolate(range[j - 1], range[j])); - } - return function(x) { - var j = d3.bisect(domain, x, 1, k) - 1; - return i[j](u[j](x)); - }; - } - d3.scale.linear = function() { - return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); - }; - function d3_scale_linear(domain, range, interpolate, clamp) { - var output, input; - function rescale() { - var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; - output = linear(domain, range, uninterpolate, interpolate); - input = linear(range, domain, uninterpolate, d3_interpolate); - return scale; - } - function scale(x) { - return output(x); - } - scale.invert = function(y) { - return input(y); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(Number); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.rangeRound = function(x) { - return scale.range(x).interpolate(d3_interpolateRound); - }; - scale.clamp = function(x) { - if (!arguments.length) return clamp; - clamp = x; - return rescale(); - }; - scale.interpolate = function(x) { - if (!arguments.length) return interpolate; - interpolate = x; - return rescale(); - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - d3_scale_linearNice(domain, m); - return rescale(); - }; - scale.copy = function() { - return d3_scale_linear(domain, range, interpolate, clamp); - }; - return rescale(); - } - function d3_scale_linearRebind(scale, linear) { - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); - } - function d3_scale_linearNice(domain, m) { - return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); - } - function d3_scale_linearTickRange(domain, m) { - if (m == null) m = 10; - var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; - if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; - extent[0] = Math.ceil(extent[0] / step) * step; - extent[1] = Math.floor(extent[1] / step) * step + step * .5; - extent[2] = step; - return extent; - } - function d3_scale_linearTicks(domain, m) { - return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); - } - function d3_scale_linearTickFormat(domain, m, format) { - var precision = -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01); - return d3.format(format ? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) { - return [ b, c, d, e, f, g, h, i || "." + (precision - (j === "%") * 2), j ].join(""); - }) : ",." + precision + "f"); - } - d3.scale.log = function() { - return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); - }; - function d3_scale_log(linear, base, positive, domain) { - function log(x) { - return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); - } - function pow(x) { - return positive ? Math.pow(base, x) : -Math.pow(base, -x); - } - function scale(x) { - return linear(log(x)); - } - scale.invert = function(x) { - return pow(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - positive = x[0] >= 0; - linear.domain((domain = x.map(Number)).map(log)); - return scale; - }; - scale.base = function(_) { - if (!arguments.length) return base; - base = +_; - linear.domain(domain.map(log)); - return scale; - }; - scale.nice = function() { - var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); - linear.domain(niced); - domain = niced.map(pow); - return scale; - }; - scale.ticks = function() { - var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; - if (isFinite(j - i)) { - if (positive) { - for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); - ticks.push(pow(i)); - } else { - ticks.push(pow(i)); - for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); - } - for (i = 0; ticks[i] < u; i++) {} - for (j = ticks.length; ticks[j - 1] > v; j--) {} - ticks = ticks.slice(i, j); - } - return ticks; - }; - scale.tickFormat = function(n, format) { - if (!arguments.length) return d3_scale_logFormat; - if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); - var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, - Math.floor), e; - return function(d) { - return d / pow(f(log(d) + e)) <= k ? format(d) : ""; - }; - }; - scale.copy = function() { - return d3_scale_log(linear.copy(), base, positive, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { - floor: function(x) { - return -Math.ceil(-x); - }, - ceil: function(x) { - return -Math.floor(-x); - } - }; - d3.scale.pow = function() { - return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); - }; - function d3_scale_pow(linear, exponent, domain) { - var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); - function scale(x) { - return linear(powp(x)); - } - scale.invert = function(x) { - return powb(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - linear.domain((domain = x.map(Number)).map(powp)); - return scale; - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - return scale.domain(d3_scale_linearNice(domain, m)); - }; - scale.exponent = function(x) { - if (!arguments.length) return exponent; - powp = d3_scale_powPow(exponent = x); - powb = d3_scale_powPow(1 / exponent); - linear.domain(domain.map(powp)); - return scale; - }; - scale.copy = function() { - return d3_scale_pow(linear.copy(), exponent, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_scale_powPow(e) { - return function(x) { - return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); - }; - } - d3.scale.sqrt = function() { - return d3.scale.pow().exponent(.5); - }; - d3.scale.ordinal = function() { - return d3_scale_ordinal([], { - t: "range", - a: [ [] ] - }); - }; - function d3_scale_ordinal(domain, ranger) { - var index, range, rangeBand; - function scale(x) { - return range[((index.get(x) || ranger.t === "range" && index.set(x, domain.push(x))) - 1) % range.length]; - } - function steps(start, step) { - return d3.range(domain.length).map(function(i) { - return start + step * i; - }); - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = []; - index = new d3_Map(); - var i = -1, n = x.length, xi; - while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); - return scale[ranger.t].apply(scale, ranger.a); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - rangeBand = 0; - ranger = { - t: "range", - a: arguments - }; - return scale; - }; - scale.rangePoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding); - range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); - rangeBand = 0; - ranger = { - t: "rangePoints", - a: arguments - }; - return scale; - }; - scale.rangeBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); - range = steps(start + step * outerPadding, step); - if (reverse) range.reverse(); - rangeBand = step * (1 - padding); - ranger = { - t: "rangeBands", - a: arguments - }; - return scale; - }; - scale.rangeRoundBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step; - range = steps(start + Math.round(error / 2), step); - if (reverse) range.reverse(); - rangeBand = Math.round(step * (1 - padding)); - ranger = { - t: "rangeRoundBands", - a: arguments - }; - return scale; - }; - scale.rangeBand = function() { - return rangeBand; - }; - scale.rangeExtent = function() { - return d3_scaleExtent(ranger.a[0]); - }; - scale.copy = function() { - return d3_scale_ordinal(domain, ranger); - }; - return scale.domain(domain); - } - d3.scale.category10 = function() { - return d3.scale.ordinal().range(d3_category10); - }; - d3.scale.category20 = function() { - return d3.scale.ordinal().range(d3_category20); - }; - d3.scale.category20b = function() { - return d3.scale.ordinal().range(d3_category20b); - }; - d3.scale.category20c = function() { - return d3.scale.ordinal().range(d3_category20c); - }; - var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); - var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); - var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); - var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); - d3.scale.quantile = function() { - return d3_scale_quantile([], []); - }; - function d3_scale_quantile(domain, range) { - var thresholds; - function rescale() { - var k = 0, q = range.length; - thresholds = []; - while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); - return scale; - } - function scale(x) { - if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.filter(function(d) { - return !isNaN(d); - }).sort(d3.ascending); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.quantiles = function() { - return thresholds; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; - }; - scale.copy = function() { - return d3_scale_quantile(domain, range); - }; - return rescale(); - } - d3.scale.quantize = function() { - return d3_scale_quantize(0, 1, [ 0, 1 ]); - }; - function d3_scale_quantize(x0, x1, range) { - var kx, i; - function scale(x) { - return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; - } - function rescale() { - kx = range.length / (x1 - x0); - i = range.length - 1; - return scale; - } - scale.domain = function(x) { - if (!arguments.length) return [ x0, x1 ]; - x0 = +x[0]; - x1 = +x[x.length - 1]; - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - y = y < 0 ? NaN : y / kx + x0; - return [ y, y + 1 / kx ]; - }; - scale.copy = function() { - return d3_scale_quantize(x0, x1, range); - }; - return rescale(); - } - d3.scale.threshold = function() { - return d3_scale_threshold([ .5 ], [ 0, 1 ]); - }; - function d3_scale_threshold(domain, range) { - function scale(x) { - if (x <= x) return range[d3.bisect(domain, x)]; - } - scale.domain = function(_) { - if (!arguments.length) return domain; - domain = _; - return scale; - }; - scale.range = function(_) { - if (!arguments.length) return range; - range = _; - return scale; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return [ domain[y - 1], domain[y] ]; - }; - scale.copy = function() { - return d3_scale_threshold(domain, range); - }; - return scale; - } - d3.scale.identity = function() { - return d3_scale_identity([ 0, 1 ]); - }; - function d3_scale_identity(domain) { - function identity(x) { - return +x; - } - identity.invert = identity; - identity.domain = identity.range = function(x) { - if (!arguments.length) return domain; - domain = x.map(identity); - return identity; - }; - identity.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - identity.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - identity.copy = function() { - return d3_scale_identity(domain); - }; - return identity; - } - d3.svg.arc = function() { - var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function arc() { - var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0, - a0 = a1, a1 = da), a1 - a0), df = da < π ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1); - return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z"; - } - arc.innerRadius = function(v) { - if (!arguments.length) return innerRadius; - innerRadius = d3_functor(v); - return arc; - }; - arc.outerRadius = function(v) { - if (!arguments.length) return outerRadius; - outerRadius = d3_functor(v); - return arc; - }; - arc.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return arc; - }; - arc.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return arc; - }; - arc.centroid = function() { - var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; - return [ Math.cos(a) * r, Math.sin(a) * r ]; - }; - return arc; - }; - var d3_svg_arcOffset = -π / 2, d3_svg_arcMax = 2 * π - 1e-6; - function d3_svg_arcInnerRadius(d) { - return d.innerRadius; - } - function d3_svg_arcOuterRadius(d) { - return d.outerRadius; - } - function d3_svg_arcStartAngle(d) { - return d.startAngle; - } - function d3_svg_arcEndAngle(d) { - return d.endAngle; - } - d3.svg.line.radial = function() { - var line = d3_svg_line(d3_svg_lineRadial); - line.radius = line.x, delete line.x; - line.angle = line.y, delete line.y; - return line; - }; - function d3_svg_lineRadial(points) { - var point, i = -1, n = points.length, r, a; - while (++i < n) { - point = points[i]; - r = point[0]; - a = point[1] + d3_svg_arcOffset; - point[0] = r * Math.cos(a); - point[1] = r * Math.sin(a); - } - return points; - } - function d3_svg_area(projection) { - var x0 = d3_svg_lineX, x1 = d3_svg_lineX, y0 = 0, y1 = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; - function area(data) { - var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { - return x; - } : d3_functor(x1), fy1 = y0 === y1 ? function() { - return y; - } : d3_functor(y1), x, y; - function segment() { - segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); - points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); - } else if (points0.length) { - segment(); - points0 = []; - points1 = []; - } - } - if (points0.length) segment(); - return segments.length ? segments.join("") : null; - } - area.x = function(_) { - if (!arguments.length) return x1; - x0 = x1 = _; - return area; - }; - area.x0 = function(_) { - if (!arguments.length) return x0; - x0 = _; - return area; - }; - area.x1 = function(_) { - if (!arguments.length) return x1; - x1 = _; - return area; - }; - area.y = function(_) { - if (!arguments.length) return y1; - y0 = y1 = _; - return area; - }; - area.y0 = function(_) { - if (!arguments.length) return y0; - y0 = _; - return area; - }; - area.y1 = function(_) { - if (!arguments.length) return y1; - y1 = _; - return area; - }; - area.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return area; - }; - area.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - interpolateReverse = interpolate.reverse || interpolate; - L = interpolate.closed ? "M" : "L"; - return area; - }; - area.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return area; - }; - return area; - } - d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; - d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; - d3.svg.area = function() { - return d3_svg_area(d3_identity); - }; - d3.svg.area.radial = function() { - var area = d3_svg_area(d3_svg_lineRadial); - area.radius = area.x, delete area.x; - area.innerRadius = area.x0, delete area.x0; - area.outerRadius = area.x1, delete area.x1; - area.angle = area.y, delete area.y; - area.startAngle = area.y0, delete area.y0; - area.endAngle = area.y1, delete area.y1; - return area; - }; - d3.svg.chord = function() { - var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function chord(d, i) { - var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); - return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; - } - function subgroup(self, f, d, i) { - var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; - return { - r: r, - a0: a0, - a1: a1, - p0: [ r * Math.cos(a0), r * Math.sin(a0) ], - p1: [ r * Math.cos(a1), r * Math.sin(a1) ] - }; - } - function equals(a, b) { - return a.a0 == b.a0 && a.a1 == b.a1; - } - function arc(r, p, a) { - return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; - } - function curve(r0, p0, r1, p1) { - return "Q 0,0 " + p1; - } - chord.radius = function(v) { - if (!arguments.length) return radius; - radius = d3_functor(v); - return chord; - }; - chord.source = function(v) { - if (!arguments.length) return source; - source = d3_functor(v); - return chord; - }; - chord.target = function(v) { - if (!arguments.length) return target; - target = d3_functor(v); - return chord; - }; - chord.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return chord; - }; - chord.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return chord; - }; - return chord; - }; - function d3_svg_chordRadius(d) { - return d.radius; - } - d3.svg.diagonal = function() { - var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; - function diagonal(d, i) { - var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { - x: p0.x, - y: m - }, { - x: p3.x, - y: m - }, p3 ]; - p = p.map(projection); - return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; - } - diagonal.source = function(x) { - if (!arguments.length) return source; - source = d3_functor(x); - return diagonal; - }; - diagonal.target = function(x) { - if (!arguments.length) return target; - target = d3_functor(x); - return diagonal; - }; - diagonal.projection = function(x) { - if (!arguments.length) return projection; - projection = x; - return diagonal; - }; - return diagonal; - }; - function d3_svg_diagonalProjection(d) { - return [ d.x, d.y ]; - } - d3.svg.diagonal.radial = function() { - var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; - diagonal.projection = function(x) { - return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; - }; - return diagonal; - }; - function d3_svg_diagonalRadialProjection(projection) { - return function() { - var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset; - return [ r * Math.cos(a), r * Math.sin(a) ]; - }; - } - d3.svg.symbol = function() { - var type = d3_svg_symbolType, size = d3_svg_symbolSize; - function symbol(d, i) { - return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); - } - symbol.type = function(x) { - if (!arguments.length) return type; - type = d3_functor(x); - return symbol; - }; - symbol.size = function(x) { - if (!arguments.length) return size; - size = d3_functor(x); - return symbol; - }; - return symbol; - }; - function d3_svg_symbolSize() { - return 64; - } - function d3_svg_symbolType() { - return "circle"; - } - function d3_svg_symbolCircle(size) { - var r = Math.sqrt(size / π); - return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; - } - var d3_svg_symbols = d3.map({ - circle: d3_svg_symbolCircle, - cross: function(size) { - var r = Math.sqrt(size / 5) / 2; - return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; - }, - diamond: function(size) { - var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; - return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; - }, - square: function(size) { - var r = Math.sqrt(size) / 2; - return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; - }, - "triangle-down": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; - }, - "triangle-up": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; - } - }); - d3.svg.symbolTypes = d3_svg_symbols.keys(); - var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); - function d3_transition(groups, id) { - d3_subclass(groups, d3_transitionPrototype); - groups.id = id; - return groups; - } - var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; - d3_transitionPrototype.call = d3_selectionPrototype.call; - d3_transitionPrototype.empty = d3_selectionPrototype.empty; - d3_transitionPrototype.node = d3_selectionPrototype.node; - d3_transitionPrototype.size = d3_selectionPrototype.size; - d3.transition = function(selection) { - return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition(); - }; - d3.transition.prototype = d3_transitionPrototype; - d3_transitionPrototype.select = function(selector) { - var id = this.id, subgroups = [], subgroup, subnode, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - d3_transitionNode(subnode, i, id, node.__transition__[id]); - subgroup.push(subnode); - } else { - subgroup.push(null); - } - } - } - return d3_transition(subgroups, id); - }; - d3_transitionPrototype.selectAll = function(selector) { - var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - transition = node.__transition__[id]; - subnodes = selector.call(node, node.__data__, i, j); - subgroups.push(subgroup = []); - for (var k = -1, o = subnodes.length; ++k < o; ) { - if (subnode = subnodes[k]) d3_transitionNode(subnode, k, id, transition); - subgroup.push(subnode); - } - } - } - } - return d3_transition(subgroups, id); - }; - d3_transitionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i)) { - subgroup.push(node); - } - } - } - return d3_transition(subgroups, this.id); - }; - d3_transitionPrototype.tween = function(name, tween) { - var id = this.id; - if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); - return d3_selection_each(this, tween == null ? function(node) { - node.__transition__[id].tween.remove(name); - } : function(node) { - node.__transition__[id].tween.set(name, tween); - }); - }; - function d3_transition_tween(groups, name, value, tween) { - var id = groups.id; - return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); - } : (value = tween(value), function(node) { - node.__transition__[id].tween.set(name, value); - })); - } - d3_transitionPrototype.attr = function(nameNS, value) { - if (arguments.length < 2) { - for (value in nameNS) this.attr(value, nameNS[value]); - return this; - } - var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrTween(b) { - return b == null ? attrNull : (b += "", function() { - var a = this.getAttribute(name), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttribute(name, i(t)); - }); - }); - } - function attrTweenNS(b) { - return b == null ? attrNullNS : (b += "", function() { - var a = this.getAttributeNS(name.space, name.local), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttributeNS(name.space, name.local, i(t)); - }); - }); - } - return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.attrTween = function(nameNS, tween) { - var name = d3.ns.qualify(nameNS); - function attrTween(d, i) { - var f = tween.call(this, d, i, this.getAttribute(name)); - return f && function(t) { - this.setAttribute(name, f(t)); - }; - } - function attrTweenNS(d, i) { - var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); - return f && function(t) { - this.setAttributeNS(name.space, name.local, f(t)); - }; - } - return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.style(priority, name[priority], value); - return this; - } - priority = ""; - } - function styleNull() { - this.style.removeProperty(name); - } - function styleString(b) { - return b == null ? styleNull : (b += "", function() { - var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; - return a !== b && (i = d3_interpolate(a, b), function(t) { - this.style.setProperty(name, i(t), priority); - }); - }); - } - return d3_transition_tween(this, "style." + name, value, styleString); - }; - d3_transitionPrototype.styleTween = function(name, tween, priority) { - if (arguments.length < 3) priority = ""; - function styleTween(d, i) { - var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); - return f && function(t) { - this.style.setProperty(name, f(t), priority); - }; - } - return this.tween("style." + name, styleTween); - }; - d3_transitionPrototype.text = function(value) { - return d3_transition_tween(this, "text", value, d3_transition_text); - }; - function d3_transition_text(b) { - if (b == null) b = ""; - return function() { - this.textContent = b; - }; - } - d3_transitionPrototype.remove = function() { - return this.each("end.transition", function() { - var p; - if (this.__transition__.count < 2 && (p = this.parentNode)) p.removeChild(this); - }); - }; - d3_transitionPrototype.ease = function(value) { - var id = this.id; - if (arguments.length < 1) return this.node().__transition__[id].ease; - if (typeof value !== "function") value = d3.ease.apply(d3, arguments); - return d3_selection_each(this, function(node) { - node.__transition__[id].ease = value; - }); - }; - d3_transitionPrototype.delay = function(value) { - var id = this.id; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].delay = +value.call(node, node.__data__, i, j); - } : (value = +value, function(node) { - node.__transition__[id].delay = value; - })); - }; - d3_transitionPrototype.duration = function(value) { - var id = this.id; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j)); - } : (value = Math.max(1, value), function(node) { - node.__transition__[id].duration = value; - })); - }; - d3_transitionPrototype.each = function(type, listener) { - var id = this.id; - if (arguments.length < 2) { - var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; - d3_transitionInheritId = id; - d3_selection_each(this, function(node, i, j) { - d3_transitionInherit = node.__transition__[id]; - type.call(node, node.__data__, i, j); - }); - d3_transitionInherit = inherit; - d3_transitionInheritId = inheritId; - } else { - d3_selection_each(this, function(node) { - var transition = node.__transition__[id]; - (transition.event || (transition.event = d3.dispatch("start", "end"))).on(type, listener); - }); - } - return this; - }; - d3_transitionPrototype.transition = function() { - var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition; - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if (node = group[i]) { - transition = Object.create(node.__transition__[id0]); - transition.delay += transition.duration; - d3_transitionNode(node, i, id1, transition); - } - subgroup.push(node); - } - } - return d3_transition(subgroups, id1); - }; - function d3_transitionNode(node, i, id, inherit) { - var lock = node.__transition__ || (node.__transition__ = { - active: 0, - count: 0 - }), transition = lock[id]; - if (!transition) { - var time = inherit.time; - transition = lock[id] = { - tween: new d3_Map(), - time: time, - ease: inherit.ease, - delay: inherit.delay, - duration: inherit.duration - }; - ++lock.count; - d3.timer(function(elapsed) { - var d = node.__data__, ease = transition.ease, delay = transition.delay, duration = transition.duration, tweened = []; - if (delay <= elapsed) return start(elapsed); - d3_timer_replace(start, delay, time); - function start(elapsed) { - if (lock.active > id) return stop(); - lock.active = id; - transition.event && transition.event.start.call(node, d, i); - transition.tween.forEach(function(key, value) { - if (value = value.call(node, d, i)) { - tweened.push(value); - } - }); - if (tick(elapsed)) return 1; - d3_timer_replace(tick, 0, time); - } - function tick(elapsed) { - if (lock.active !== id) return stop(); - var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length; - while (n > 0) { - tweened[--n].call(node, e); - } - if (t >= 1) { - transition.event && transition.event.end.call(node, d, i); - return stop(); - } - } - function stop() { - if (--lock.count) delete lock[id]; else delete node.__transition__; - return 1; - } - }, 0, time); - } - } - d3.svg.axis = function() { - var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; - function axis(g) { - g.each(function() { - var g = d3.select(this); - var ticks = tickValues == null ? scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain() : tickValues, tickFormat = tickFormat_ == null ? scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6), tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(), tickUpdate = d3.transition(tick).style("opacity", 1), tickTransform; - var range = d3_scaleRange(scale), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), - d3.transition(path)); - var scale1 = scale.copy(), scale0 = this.__chart__ || scale1; - this.__chart__ = scale1; - tickEnter.append("line"); - tickEnter.append("text"); - var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); - switch (orient) { - case "bottom": - { - tickTransform = d3_svg_axisX; - lineEnter.attr("y2", innerTickSize); - textEnter.attr("y", Math.max(innerTickSize, 0) + tickPadding); - lineUpdate.attr("x2", 0).attr("y2", innerTickSize); - textUpdate.attr("x", 0).attr("y", Math.max(innerTickSize, 0) + tickPadding); - text.attr("dy", ".71em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize); - break; - } - - case "top": - { - tickTransform = d3_svg_axisX; - lineEnter.attr("y2", -innerTickSize); - textEnter.attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); - lineUpdate.attr("x2", 0).attr("y2", -innerTickSize); - textUpdate.attr("x", 0).attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); - text.attr("dy", "0em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize); - break; - } - - case "left": - { - tickTransform = d3_svg_axisY; - lineEnter.attr("x2", -innerTickSize); - textEnter.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)); - lineUpdate.attr("x2", -innerTickSize).attr("y2", 0); - textUpdate.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "end"); - pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize); - break; - } - - case "right": - { - tickTransform = d3_svg_axisY; - lineEnter.attr("x2", innerTickSize); - textEnter.attr("x", Math.max(innerTickSize, 0) + tickPadding); - lineUpdate.attr("x2", innerTickSize).attr("y2", 0); - textUpdate.attr("x", Math.max(innerTickSize, 0) + tickPadding).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "start"); - pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize); - break; - } - } - if (scale.rangeBand) { - var dx = scale1.rangeBand() / 2, x = function(d) { - return scale1(d) + dx; - }; - tickEnter.call(tickTransform, x); - tickUpdate.call(tickTransform, x); - } else { - tickEnter.call(tickTransform, scale0); - tickUpdate.call(tickTransform, scale1); - tickExit.call(tickTransform, scale1); - } - }); - } - axis.scale = function(x) { - if (!arguments.length) return scale; - scale = x; - return axis; - }; - axis.orient = function(x) { - if (!arguments.length) return orient; - orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; - return axis; - }; - axis.ticks = function() { - if (!arguments.length) return tickArguments_; - tickArguments_ = arguments; - return axis; - }; - axis.tickValues = function(x) { - if (!arguments.length) return tickValues; - tickValues = x; - return axis; - }; - axis.tickFormat = function(x) { - if (!arguments.length) return tickFormat_; - tickFormat_ = x; - return axis; - }; - axis.tickSize = function(x) { - var n = arguments.length; - if (!n) return innerTickSize; - innerTickSize = +x; - outerTickSize = +arguments[n - 1]; - return axis; - }; - axis.innerTickSize = function(x) { - if (!arguments.length) return innerTickSize; - innerTickSize = +x; - return axis; - }; - axis.outerTickSize = function(x) { - if (!arguments.length) return outerTickSize; - outerTickSize = +x; - return axis; - }; - axis.tickPadding = function(x) { - if (!arguments.length) return tickPadding; - tickPadding = +x; - return axis; - }; - axis.tickSubdivide = function() { - return arguments.length && axis; - }; - return axis; - }; - var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { - top: 1, - right: 1, - bottom: 1, - left: 1 - }; - function d3_svg_axisX(selection, x) { - selection.attr("transform", function(d) { - return "translate(" + x(d) + ",0)"; - }); - } - function d3_svg_axisY(selection, y) { - selection.attr("transform", function(d) { - return "translate(0," + y(d) + ")"; - }); - } - d3.svg.brush = function() { - var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; - function brush(g) { - g.each(function() { - var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); - var background = g.selectAll(".background").data([ 0 ]); - background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); - g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); - var resize = g.selectAll(".resize").data(resizes, d3_identity); - resize.exit().remove(); - resize.enter().append("g").attr("class", function(d) { - return "resize " + d; - }).style("cursor", function(d) { - return d3_svg_brushCursor[d]; - }).append("rect").attr("x", function(d) { - return /[ew]$/.test(d) ? -3 : null; - }).attr("y", function(d) { - return /^[ns]/.test(d) ? -3 : null; - }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); - resize.style("display", brush.empty() ? "none" : null); - var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; - if (x) { - range = d3_scaleRange(x); - backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); - redrawX(gUpdate); - } - if (y) { - range = d3_scaleRange(y); - backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); - redrawY(gUpdate); - } - redraw(gUpdate); - }); - } - brush.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), extent1 = { - x: xExtent, - y: yExtent, - i: xExtentDomain, - j: yExtentDomain - }, extent0 = this.__chart__ || extent1; - this.__chart__ = extent1; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.brush", function() { - xExtentDomain = extent0.i; - yExtentDomain = extent0.j; - xExtent = extent0.x; - yExtent = extent0.y; - event_({ - type: "brushstart" - }); - }).tween("brush:brush", function() { - var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); - xExtentDomain = yExtentDomain = null; - return function(t) { - xExtent = extent1.x = xi(t); - yExtent = extent1.y = yi(t); - event_({ - type: "brush", - mode: "resize" - }); - }; - }).each("end.brush", function() { - xExtentDomain = extent1.i; - yExtentDomain = extent1.j; - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - }); - } else { - event_({ - type: "brushstart" - }); - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - } - }); - }; - function redraw(g) { - g.selectAll(".resize").attr("transform", function(d) { - return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; - }); - } - function redrawX(g) { - g.select(".extent").attr("x", xExtent[0]); - g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); - } - function redrawY(g) { - g.select(".extent").attr("y", yExtent[0]); - g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); - } - function brushstart() { - var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = d3.mouse(target), offset; - var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup); - if (d3.event.changedTouches) { - w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); - } else { - w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); - } - g.interrupt().selectAll("*").interrupt(); - if (dragging) { - origin[0] = xExtent[0] - origin[0]; - origin[1] = yExtent[0] - origin[1]; - } else if (resizing) { - var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); - offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; - origin[0] = xExtent[ex]; - origin[1] = yExtent[ey]; - } else if (d3.event.altKey) center = origin.slice(); - g.style("pointer-events", "none").selectAll(".resize").style("display", null); - d3.select("body").style("cursor", eventTarget.style("cursor")); - event_({ - type: "brushstart" - }); - brushmove(); - function keydown() { - if (d3.event.keyCode == 32) { - if (!dragging) { - center = null; - origin[0] -= xExtent[1]; - origin[1] -= yExtent[1]; - dragging = 2; - } - d3_eventPreventDefault(); - } - } - function keyup() { - if (d3.event.keyCode == 32 && dragging == 2) { - origin[0] += xExtent[1]; - origin[1] += yExtent[1]; - dragging = 0; - d3_eventPreventDefault(); - } - } - function brushmove() { - var point = d3.mouse(target), moved = false; - if (offset) { - point[0] += offset[0]; - point[1] += offset[1]; - } - if (!dragging) { - if (d3.event.altKey) { - if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; - origin[0] = xExtent[+(point[0] < center[0])]; - origin[1] = yExtent[+(point[1] < center[1])]; - } else center = null; - } - if (resizingX && move1(point, x, 0)) { - redrawX(g); - moved = true; - } - if (resizingY && move1(point, y, 1)) { - redrawY(g); - moved = true; - } - if (moved) { - redraw(g); - event_({ - type: "brush", - mode: dragging ? "move" : "resize" - }); - } - } - function move1(point, scale, i) { - var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; - if (dragging) { - r0 -= position; - r1 -= size + position; - } - min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; - if (dragging) { - max = (min += position) + size; - } else { - if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); - if (position < min) { - max = min; - min = position; - } else { - max = position; - } - } - if (extent[0] != min || extent[1] != max) { - if (i) yExtentDomain = null; else xExtentDomain = null; - extent[0] = min; - extent[1] = max; - return true; - } - } - function brushend() { - brushmove(); - g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); - d3.select("body").style("cursor", null); - w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); - dragRestore(); - event_({ - type: "brushend" - }); - } - } - brush.x = function(z) { - if (!arguments.length) return x; - x = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.y = function(z) { - if (!arguments.length) return y; - y = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.clamp = function(z) { - if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; - if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; - return brush; - }; - brush.extent = function(z) { - var x0, x1, y0, y1, t; - if (!arguments.length) { - if (x) { - if (xExtentDomain) { - x0 = xExtentDomain[0], x1 = xExtentDomain[1]; - } else { - x0 = xExtent[0], x1 = xExtent[1]; - if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - } - } - if (y) { - if (yExtentDomain) { - y0 = yExtentDomain[0], y1 = yExtentDomain[1]; - } else { - y0 = yExtent[0], y1 = yExtent[1]; - if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - } - } - return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; - } - if (x) { - x0 = z[0], x1 = z[1]; - if (y) x0 = x0[0], x1 = x1[0]; - xExtentDomain = [ x0, x1 ]; - if (x.invert) x0 = x(x0), x1 = x(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; - } - if (y) { - y0 = z[0], y1 = z[1]; - if (x) y0 = y0[1], y1 = y1[1]; - yExtentDomain = [ y0, y1 ]; - if (y.invert) y0 = y(y0), y1 = y(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; - } - return brush; - }; - brush.clear = function() { - if (!brush.empty()) { - xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; - xExtentDomain = yExtentDomain = null; - } - return brush; - }; - brush.empty = function() { - return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; - }; - return d3.rebind(brush, event, "on"); - }; - var d3_svg_brushCursor = { - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" - }; - var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; - var d3_time = d3.time = {}, d3_date = Date, d3_time_daySymbols = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; - function d3_date_utc() { - this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); - } - d3_date_utc.prototype = { - getDate: function() { - return this._.getUTCDate(); - }, - getDay: function() { - return this._.getUTCDay(); - }, - getFullYear: function() { - return this._.getUTCFullYear(); - }, - getHours: function() { - return this._.getUTCHours(); - }, - getMilliseconds: function() { - return this._.getUTCMilliseconds(); - }, - getMinutes: function() { - return this._.getUTCMinutes(); - }, - getMonth: function() { - return this._.getUTCMonth(); - }, - getSeconds: function() { - return this._.getUTCSeconds(); - }, - getTime: function() { - return this._.getTime(); - }, - getTimezoneOffset: function() { - return 0; - }, - valueOf: function() { - return this._.valueOf(); - }, - setDate: function() { - d3_time_prototype.setUTCDate.apply(this._, arguments); - }, - setDay: function() { - d3_time_prototype.setUTCDay.apply(this._, arguments); - }, - setFullYear: function() { - d3_time_prototype.setUTCFullYear.apply(this._, arguments); - }, - setHours: function() { - d3_time_prototype.setUTCHours.apply(this._, arguments); - }, - setMilliseconds: function() { - d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); - }, - setMinutes: function() { - d3_time_prototype.setUTCMinutes.apply(this._, arguments); - }, - setMonth: function() { - d3_time_prototype.setUTCMonth.apply(this._, arguments); - }, - setSeconds: function() { - d3_time_prototype.setUTCSeconds.apply(this._, arguments); - }, - setTime: function() { - d3_time_prototype.setTime.apply(this._, arguments); - } - }; - var d3_time_prototype = Date.prototype; - var d3_time_formatDateTime = "%a %b %e %X %Y", d3_time_formatDate = "%m/%d/%Y", d3_time_formatTime = "%H:%M:%S"; - var d3_time_days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], d3_time_dayAbbreviations = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], d3_time_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], d3_time_monthAbbreviations = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; - function d3_time_interval(local, step, number) { - function round(date) { - var d0 = local(date), d1 = offset(d0, 1); - return date - d0 < d1 - date ? d0 : d1; - } - function ceil(date) { - step(date = local(new d3_date(date - 1)), 1); - return date; - } - function offset(date, k) { - step(date = new d3_date(+date), k); - return date; - } - function range(t0, t1, dt) { - var time = ceil(t0), times = []; - if (dt > 1) { - while (time < t1) { - if (!(number(time) % dt)) times.push(new Date(+time)); - step(time, 1); - } - } else { - while (time < t1) times.push(new Date(+time)), step(time, 1); - } - return times; - } - function range_utc(t0, t1, dt) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = t0; - return range(utc, t1, dt); - } finally { - d3_date = Date; - } - } - local.floor = local; - local.round = round; - local.ceil = ceil; - local.offset = offset; - local.range = range; - var utc = local.utc = d3_time_interval_utc(local); - utc.floor = utc; - utc.round = d3_time_interval_utc(round); - utc.ceil = d3_time_interval_utc(ceil); - utc.offset = d3_time_interval_utc(offset); - utc.range = range_utc; - return local; - } - function d3_time_interval_utc(method) { - return function(date, k) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = date; - return method(utc, k)._; - } finally { - d3_date = Date; - } - }; - } - d3_time.year = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setMonth(0, 1); - return date; - }, function(date, offset) { - date.setFullYear(date.getFullYear() + offset); - }, function(date) { - return date.getFullYear(); - }); - d3_time.years = d3_time.year.range; - d3_time.years.utc = d3_time.year.utc.range; - d3_time.day = d3_time_interval(function(date) { - var day = new d3_date(2e3, 0); - day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - return day; - }, function(date, offset) { - date.setDate(date.getDate() + offset); - }, function(date) { - return date.getDate() - 1; - }); - d3_time.days = d3_time.day.range; - d3_time.days.utc = d3_time.day.utc.range; - d3_time.dayOfYear = function(date) { - var year = d3_time.year(date); - return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); - }; - d3_time_daySymbols.forEach(function(day, i) { - day = day.toLowerCase(); - i = 7 - i; - var interval = d3_time[day] = d3_time_interval(function(date) { - (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); - return date; - }, function(date, offset) { - date.setDate(date.getDate() + Math.floor(offset) * 7); - }, function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); - }); - d3_time[day + "s"] = interval.range; - d3_time[day + "s"].utc = interval.utc.range; - d3_time[day + "OfYear"] = function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); - }; - }); - d3_time.week = d3_time.sunday; - d3_time.weeks = d3_time.sunday.range; - d3_time.weeks.utc = d3_time.sunday.utc.range; - d3_time.weekOfYear = d3_time.sundayOfYear; - d3_time.format = d3_time_format; - function d3_time_format(template) { - var n = template.length; - function format(date) { - var string = [], i = -1, j = 0, c, p, f; - while (++i < n) { - if (template.charCodeAt(i) === 37) { - string.push(template.substring(j, i)); - if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); - if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); - string.push(c); - j = i + 1; - } - } - string.push(template.substring(j, i)); - return string.join(""); - } - format.parse = function(string) { - var d = { - y: 1900, - m: 0, - d: 1, - H: 0, - M: 0, - S: 0, - L: 0, - Z: null - }, i = d3_time_parse(d, template, string, 0); - if (i != string.length) return null; - if ("p" in d) d.H = d.H % 12 + d.p * 12; - var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); - if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { - date.setFullYear(d.y, 0, 1); - date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); - } else date.setFullYear(d.y, d.m, d.d); - date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L); - return localZ ? date._ : date; - }; - format.toString = function() { - return template; - }; - return format; - } - function d3_time_parse(date, template, string, j) { - var c, p, t, i = 0, n = template.length, m = string.length; - while (i < n) { - if (j >= m) return -1; - c = template.charCodeAt(i++); - if (c === 37) { - t = template.charAt(i++); - p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; - if (!p || (j = p(date, string, j)) < 0) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - return j; - } - function d3_time_formatRe(names) { - return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); - } - function d3_time_formatLookup(names) { - var map = new d3_Map(), i = -1, n = names.length; - while (++i < n) map.set(names[i].toLowerCase(), i); - return map; - } - function d3_time_formatPad(value, fill, width) { - var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); - } - var d3_time_dayRe = d3_time_formatRe(d3_time_days), d3_time_dayLookup = d3_time_formatLookup(d3_time_days), d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations), d3_time_dayAbbrevLookup = d3_time_formatLookup(d3_time_dayAbbreviations), d3_time_monthRe = d3_time_formatRe(d3_time_months), d3_time_monthLookup = d3_time_formatLookup(d3_time_months), d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations), d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations), d3_time_percentRe = /^%/; - var d3_time_formatPads = { - "-": "", - _: " ", - "0": "0" - }; - var d3_time_formats = { - a: function(d) { - return d3_time_dayAbbreviations[d.getDay()]; - }, - A: function(d) { - return d3_time_days[d.getDay()]; - }, - b: function(d) { - return d3_time_monthAbbreviations[d.getMonth()]; - }, - B: function(d) { - return d3_time_months[d.getMonth()]; - }, - c: d3_time_format(d3_time_formatDateTime), - d: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - e: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - H: function(d, p) { - return d3_time_formatPad(d.getHours(), p, 2); - }, - I: function(d, p) { - return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); - }, - j: function(d, p) { - return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); - }, - L: function(d, p) { - return d3_time_formatPad(d.getMilliseconds(), p, 3); - }, - m: function(d, p) { - return d3_time_formatPad(d.getMonth() + 1, p, 2); - }, - M: function(d, p) { - return d3_time_formatPad(d.getMinutes(), p, 2); - }, - p: function(d) { - return d.getHours() >= 12 ? "PM" : "AM"; - }, - S: function(d, p) { - return d3_time_formatPad(d.getSeconds(), p, 2); - }, - U: function(d, p) { - return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); - }, - w: function(d) { - return d.getDay(); - }, - W: function(d, p) { - return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); - }, - x: d3_time_format(d3_time_formatDate), - X: d3_time_format(d3_time_formatTime), - y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 100, p, 2); - }, - Y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); - }, - Z: d3_time_zone, - "%": function() { - return "%"; - } - }; - var d3_time_parsers = { - a: d3_time_parseWeekdayAbbrev, - A: d3_time_parseWeekday, - b: d3_time_parseMonthAbbrev, - B: d3_time_parseMonth, - c: d3_time_parseLocaleFull, - d: d3_time_parseDay, - e: d3_time_parseDay, - H: d3_time_parseHour24, - I: d3_time_parseHour24, - j: d3_time_parseDayOfYear, - L: d3_time_parseMilliseconds, - m: d3_time_parseMonthNumber, - M: d3_time_parseMinutes, - p: d3_time_parseAmPm, - S: d3_time_parseSeconds, - U: d3_time_parseWeekNumberSunday, - w: d3_time_parseWeekdayNumber, - W: d3_time_parseWeekNumberMonday, - x: d3_time_parseLocaleDate, - X: d3_time_parseLocaleTime, - y: d3_time_parseYear, - Y: d3_time_parseFullYear, - Z: d3_time_parseZone, - "%": d3_time_parseLiteralPercent - }; - function d3_time_parseWeekdayAbbrev(date, string, i) { - d3_time_dayAbbrevRe.lastIndex = 0; - var n = d3_time_dayAbbrevRe.exec(string.substring(i)); - return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseWeekday(date, string, i) { - d3_time_dayRe.lastIndex = 0; - var n = d3_time_dayRe.exec(string.substring(i)); - return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseWeekdayNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 1)); - return n ? (date.w = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberSunday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i)); - return n ? (date.U = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberMonday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i)); - return n ? (date.W = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMonthAbbrev(date, string, i) { - d3_time_monthAbbrevRe.lastIndex = 0; - var n = d3_time_monthAbbrevRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonth(date, string, i) { - d3_time_monthRe.lastIndex = 0; - var n = d3_time_monthRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseLocaleFull(date, string, i) { - return d3_time_parse(date, d3_time_formats.c.toString(), string, i); - } - function d3_time_parseLocaleDate(date, string, i) { - return d3_time_parse(date, d3_time_formats.x.toString(), string, i); - } - function d3_time_parseLocaleTime(date, string, i) { - return d3_time_parse(date, d3_time_formats.X.toString(), string, i); - } - function d3_time_parseFullYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 4)); - return n ? (date.y = +n[0], i + n[0].length) : -1; - } - function d3_time_parseYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; - } - function d3_time_parseZone(date, string, i) { - return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) ? (date.Z = +string, - i + 5) : -1; - } - function d3_time_expandYear(d) { - return d + (d > 68 ? 1900 : 2e3); - } - function d3_time_parseMonthNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.m = n[0] - 1, i + n[0].length) : -1; - } - function d3_time_parseDay(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.d = +n[0], i + n[0].length) : -1; - } - function d3_time_parseDayOfYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.j = +n[0], i + n[0].length) : -1; - } - function d3_time_parseHour24(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.H = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMinutes(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.M = +n[0], i + n[0].length) : -1; - } - function d3_time_parseSeconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.S = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMilliseconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.L = +n[0], i + n[0].length) : -1; - } - var d3_time_numberRe = /^\s*\d+/; - function d3_time_parseAmPm(date, string, i) { - var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase()); - return n == null ? -1 : (date.p = n, i); - } - var d3_time_amPmLookup = d3.map({ - am: 0, - pm: 1 - }); - function d3_time_zone(d) { - var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(Math.abs(z) / 60), zm = Math.abs(z) % 60; - return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); - } - function d3_time_parseLiteralPercent(date, string, i) { - d3_time_percentRe.lastIndex = 0; - var n = d3_time_percentRe.exec(string.substring(i, i + 1)); - return n ? i + n[0].length : -1; - } - d3_time_format.utc = d3_time_formatUtc; - function d3_time_formatUtc(template) { - var local = d3_time_format(template); - function format(date) { - try { - d3_date = d3_date_utc; - var utc = new d3_date(); - utc._ = date; - return local(utc); - } finally { - d3_date = Date; - } - } - format.parse = function(string) { - try { - d3_date = d3_date_utc; - var date = local.parse(string); - return date && date._; - } finally { - d3_date = Date; - } - }; - format.toString = local.toString; - return format; - } - var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); - d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; - function d3_time_formatIsoNative(date) { - return date.toISOString(); - } - d3_time_formatIsoNative.parse = function(string) { - var date = new Date(string); - return isNaN(date) ? null : date; - }; - d3_time_formatIsoNative.toString = d3_time_formatIso.toString; - d3_time.second = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 1e3) * 1e3); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 1e3); - }, function(date) { - return date.getSeconds(); - }); - d3_time.seconds = d3_time.second.range; - d3_time.seconds.utc = d3_time.second.utc.range; - d3_time.minute = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 6e4) * 6e4); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 6e4); - }, function(date) { - return date.getMinutes(); - }); - d3_time.minutes = d3_time.minute.range; - d3_time.minutes.utc = d3_time.minute.utc.range; - d3_time.hour = d3_time_interval(function(date) { - var timezone = date.getTimezoneOffset() / 60; - return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 36e5); - }, function(date) { - return date.getHours(); - }); - d3_time.hours = d3_time.hour.range; - d3_time.hours.utc = d3_time.hour.utc.range; - d3_time.month = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setDate(1); - return date; - }, function(date, offset) { - date.setMonth(date.getMonth() + offset); - }, function(date) { - return date.getMonth(); - }); - d3_time.months = d3_time.month.range; - d3_time.months.utc = d3_time.month.utc.range; - function d3_time_scale(linear, methods, format) { - function scale(x) { - return linear(x); - } - scale.invert = function(x) { - return d3_time_scaleDate(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(d3_time_scaleDate); - linear.domain(x); - return scale; - }; - function tickMethod(extent, count) { - var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); - return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { - return d / 31536e6; - }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; - } - scale.nice = function(interval, skip) { - var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); - if (method) interval = method[0], skip = method[1]; - function skipped(date) { - return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; - } - return scale.domain(d3_scale_nice(domain, skip > 1 ? { - floor: function(date) { - while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); - return date; - }, - ceil: function(date) { - while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); - return date; - } - } : interval)); - }; - scale.ticks = function(interval, skip) { - var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { - range: interval - }, skip ]; - if (method) interval = method[0], skip = method[1]; - return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); - }; - scale.tickFormat = function() { - return format; - }; - scale.copy = function() { - return d3_time_scale(linear.copy(), methods, format); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_time_scaleDate(t) { - return new Date(t); - } - function d3_time_scaleFormat(formats) { - return function(date) { - var i = formats.length - 1, f = formats[i]; - while (!f[1](date)) f = formats[--i]; - return f[0](date); - }; - } - var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; - var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; - var d3_time_scaleLocalFormats = [ [ d3_time_format("%Y"), d3_true ], [ d3_time_format("%B"), function(d) { - return d.getMonth(); - } ], [ d3_time_format("%b %d"), function(d) { - return d.getDate() != 1; - } ], [ d3_time_format("%a %d"), function(d) { - return d.getDay() && d.getDate() != 1; - } ], [ d3_time_format("%I %p"), function(d) { - return d.getHours(); - } ], [ d3_time_format("%I:%M"), function(d) { - return d.getMinutes(); - } ], [ d3_time_format(":%S"), function(d) { - return d.getSeconds(); - } ], [ d3_time_format(".%L"), function(d) { - return d.getMilliseconds(); - } ] ]; - var d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); - d3_time_scaleLocalMethods.year = d3_time.year; - d3_time.scale = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); - }; - var d3_time_scaleMilliseconds = { - range: function(start, stop, step) { - return d3.range(+start, +stop, step).map(d3_time_scaleDate); - } - }; - var d3_time_scaleUTCMethods = d3_time_scaleLocalMethods.map(function(m) { - return [ m[0].utc, m[1] ]; - }); - var d3_time_scaleUTCFormats = [ [ d3_time_formatUtc("%Y"), d3_true ], [ d3_time_formatUtc("%B"), function(d) { - return d.getUTCMonth(); - } ], [ d3_time_formatUtc("%b %d"), function(d) { - return d.getUTCDate() != 1; - } ], [ d3_time_formatUtc("%a %d"), function(d) { - return d.getUTCDay() && d.getUTCDate() != 1; - } ], [ d3_time_formatUtc("%I %p"), function(d) { - return d.getUTCHours(); - } ], [ d3_time_formatUtc("%I:%M"), function(d) { - return d.getUTCMinutes(); - } ], [ d3_time_formatUtc(":%S"), function(d) { - return d.getUTCSeconds(); - } ], [ d3_time_formatUtc(".%L"), function(d) { - return d.getUTCMilliseconds(); - } ] ]; - var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats); - d3_time_scaleUTCMethods.year = d3_time.year.utc; - d3_time.scale.utc = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat); - }; - d3.text = d3_xhrType(function(request) { - return request.responseText; - }); - d3.json = function(url, callback) { - return d3_xhr(url, "application/json", d3_json, callback); - }; - function d3_json(request) { - return JSON.parse(request.responseText); - } - d3.html = function(url, callback) { - return d3_xhr(url, "text/html", d3_html, callback); - }; - function d3_html(request) { - var range = d3_document.createRange(); - range.selectNode(d3_document.body); - return range.createContextualFragment(request.responseText); - } - d3.xml = d3_xhrType(function(request) { - return request.responseXML; - }); - return d3; -}(); \ No newline at end of file diff --git a/d3.min.js b/d3.min.js deleted file mode 100644 index 35338a0470d212..00000000000000 --- a/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -d3=function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(){}function o(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function a(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=Do.length;r>e;++e){var u=Do[e]+t;if(u in n)return u}}function c(){}function l(){}function s(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function T(n){return Lo(n,Io),n}function q(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.substring(0,a));var s=Zo.get(n);return s&&(n=s,l=j),a?t?u:r:t?c:i}function D(n,t){return function(e){var r=mo.event;mo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{mo.event=r}}}function j(n,t){var e=D(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function L(){var n=".dragsuppress-"+ ++Xo,t="touchmove"+n,e="selectstart"+n,r="dragstart"+n,u="click"+n,i=mo.select(_o).on(t,f).on(e,f).on(r,f),o=bo.style,a=o[Vo];return o[Vo]="none",function(t){function e(){i.on(u,null)}i.on(n,null),o[Vo]=a,t&&(i.on(u,function(){f(),e()},!0),setTimeout(e,0))}}function H(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>$o&&(_o.scrollX||_o.scrollY)){e=mo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();$o=!(u.f||u.e),e.remove()}return $o?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function F(n){return n>0?1:0>n?-1:0}function P(n){return n>1?0:-1>n?Bo:Math.acos(n)}function O(n){return n>1?Bo/2:-1>n?-Bo/2:Math.asin(n)}function R(n){return(Math.exp(n)-Math.exp(-n))/2}function Y(n){return(Math.exp(n)+Math.exp(-n))/2}function I(n){return R(n)/Y(n)}function U(n){return(n=Math.sin(n/2))*n}function Z(){}function V(n,t,e){return new X(n,t,e)}function X(n,t,e){this.h=n,this.s=t,this.l=e}function $(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,ot(u(n+120),u(n),u(n-120))}function B(n,t,e){return new W(n,t,e)}function W(n,t,e){this.h=n,this.c=t,this.l=e}function J(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),G(e,Math.cos(n*=Go)*t,Math.sin(n)*t)}function G(n,t,e){return new K(n,t,e)}function K(n,t,e){this.l=n,this.a=t,this.b=e}function Q(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=tt(u)*ca,r=tt(r)*la,i=tt(i)*sa,ot(rt(3.2404542*u-1.5371385*r-.4985314*i),rt(-.969266*u+1.8760108*r+.041556*i),rt(.0556434*u-.2040259*r+1.0572252*i))}function nt(n,t,e){return n>0?B(Math.atan2(e,t)*Ko,Math.sqrt(t*t+e*e),n):B(0/0,0/0,n)}function tt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function et(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function rt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ut(n){return ot(n>>16,255&n>>8,255&n)}function it(n){return ut(n)+""}function ot(n,t,e){return new at(n,t,e)}function at(n,t,e){this.r=n,this.g=t,this.b=e}function ct(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function lt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(gt(u[0]),gt(u[1]),gt(u[2]))}return(i=ga.get(n))?t(i.r,i.g,i.b):(null!=n&&"#"===n.charAt(0)&&(4===n.length?(o=n.charAt(1),o+=o,a=n.charAt(2),a+=a,c=n.charAt(3),c+=c):7===n.length&&(o=n.substring(1,3),a=n.substring(3,5),c=n.substring(5,7)),o=parseInt(o,16),a=parseInt(a,16),c=parseInt(c,16)),t(o,a,c))}function st(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),V(r,u,c)}function ft(n,t,e){n=ht(n),t=ht(t),e=ht(e);var r=et((.4124564*n+.3575761*t+.1804375*e)/ca),u=et((.2126729*n+.7151522*t+.072175*e)/la),i=et((.0193339*n+.119192*t+.9503041*e)/sa);return G(116*u-16,500*(r-u),200*(u-i))}function ht(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function gt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function pt(n){return"function"==typeof n?n:function(){return n}}function dt(n){return n}function vt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),mt(t,e,n,r)}}function mt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=mo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!_o.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=mo.event;mo.event=n;try{o.progress.call(i,c)}finally{mo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Mo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},mo.rebind(i,o,"on"),null==r?i:i.get(yt(r))}function yt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Mt(){var n=bt(),t=_t()-n;t>24?(isFinite(t)&&(clearTimeout(ma),ma=setTimeout(Mt,t)),va=0):(va=1,Ma(Mt))}function xt(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now()),ya.callback=n,ya.time=e+t}function bt(){var n=Date.now();for(ya=pa;ya;)n>=ya.time&&(ya.flush=ya.callback(n-ya.time)),ya=ya.next;return n}function _t(){for(var n,t=pa,e=1/0;t;)t.flush?t=n?n.next=t.next:pa=t.next:(t.time8?function(n){return n/e}:function(n){return n*e},symbol:n}}function St(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Et(n){return n+""}function kt(){}function At(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function Nt(n,t){n&&za.hasOwnProperty(n.type)&&za[n.type](n,t)}function Tt(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++ua;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c={point:e,points:n,other:null,visited:!1,entry:!0,subject:!0},l={point:e,points:[e],other:c,visited:!1,entry:!1,subject:!1};c.other=l,i.push(c),o.push(l),c={point:r,points:[r],other:null,visited:!1,entry:!1,subject:!0},l={point:r,points:[r],other:c,visited:!1,entry:!0,subject:!1},c.other=l,i.push(c),o.push(l)}}),o.sort(t),$t(i),$t(o),i.length){if(e)for(var a=1,c=!e(o[0].point),l=o.length;l>a;++a)o[a].entry=c=!c;for(var s,f,h,g=i[0];;){for(s=g;s.visited;)if((s=s.next)===g)return;f=s.points,u.lineStart();do{if(s.visited=s.other.visited=!0,s.entry){if(s.subject)for(var a=0;a=0;)u.point((h=f[a])[0],h[1])}else r(s.point,s.prev.point,-1,u);s=s.prev}s=s.other,f=s.points}while(!s.visited);u.lineEnd()}}}function $t(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r1&&2&t&&e.push(e.pop().concat(e.shift())),h.push(e.filter(Wt))}}var h,g,p,d=t(u),v={point:i,lineStart:a,lineEnd:c,polygonStart:function(){v.point=l,v.lineStart=s,v.lineEnd=f,h=[],g=[],u.polygonStart()},polygonEnd:function(){v.point=i,v.lineStart=a,v.lineEnd=c,h=mo.merge(h),h.length?Xt(h,Gt,null,e,u):r(g)&&(u.lineStart(),e(null,null,1,u),u.lineEnd()),u.polygonEnd(),h=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},m=Jt(),y=t(m);return v}}function Wt(n){return n.length>1}function Jt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:c,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Gt(n,t){return((n=n.point)[0]<0?n[1]-Bo/2-Wo:Bo/2-n[1])-((t=t.point)[0]<0?t[1]-Bo/2-Wo:Bo/2-t[1])}function Kt(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;Da.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Bo/4,p=Math.sin(g),d=Math.cos(g),v=1;;){v===s&&(v=0),n=l[v];var m=n[0],y=n[1]/2+Bo/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=Math.abs(b)>Bo,w=p*M;if(Da.add(Math.atan2(w*Math.sin(b),d*x+w*Math.cos(b))),i+=_?b+(b>=0?2:-2)*Bo:b,_^h>=e^m>=e){var S=jt(Ct(f),Ct(n));Ft(S);var E=jt(u,S);Ft(E);var k=(_^b>=0?-1:1)*O(E[2]);r>k&&(o+=_^b>=0?1:-1)}if(!v++)break;h=m,p=M,d=x,f=n}}return(-Wo>i||Wo>i&&0>Da)^1&o}function Qt(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Bo:-Bo,c=Math.abs(i-e);Math.abs(c-Bo)0?Bo/2:-Bo/2),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Bo&&(Math.abs(e-u)Wo?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function te(n,t,e,r){var u;if(null==n)u=e*Bo/2,r.point(-Bo,u),r.point(0,u),r.point(Bo,u),r.point(Bo,0),r.point(Bo,-u),r.point(0,-u),r.point(-Bo,-u),r.point(-Bo,0),r.point(-Bo,u);else if(Math.abs(n[0]-t[0])>Wo){var i=(n[0]o}function e(n){var e,i,o,c,s;return{lineStart:function(){c=o=!1,s=1},point:function(f,h){var g,p=[f,h],d=t(f,h),v=a?d?0:u(f,h):d?u(f+(0>f?Bo:-Bo),h):0;if(!e&&(c=o=d)&&n.lineStart(),d!==o&&(g=r(e,p),(Ot(e,g)||Ot(p,g))&&(p[0]+=Wo,p[1]+=Wo,d=t(p[0],p[1]))),d!==o)s=0,d?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(l&&e&&a^d){var m;v&i||!(m=r(p,e,!0))||(s=0,a?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!d||e&&Ot(e,p)||n.point(p[0],p[1]),e=p,o=d,i=v},lineEnd:function(){o&&n.lineEnd(),e=null},clean:function(){return s|(c&&o)<<1}}}function r(n,t,e){var r=Ct(n),u=Ct(t),i=[1,0,0],a=jt(r,u),c=Dt(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=o*c/s,h=-o*l/s,g=jt(i,a),p=Ht(i,f),d=Ht(a,h);Lt(p,d);var v=g,m=Dt(p,v),y=Dt(v,v),M=m*m-y*(Dt(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=Ht(v,(-m-x)/y);if(Lt(b,p),b=Pt(b),!e)return b;var _,w=n[0],S=t[0],E=n[1],k=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=Math.abs(A-Bo)A;if(!N&&E>k&&(_=E,E=k,k=_),T?N?E+k>0^b[1]<(Math.abs(b[0]-w)Bo^(w<=b[0]&&b[0]<=S)){var q=Ht(v,(-m+x)/y);return Lt(q,p),[b,Pt(q)]}}}function u(t,e){var r=a?n:Bo-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}function i(n){return Kt(c,n)}var o=Math.cos(n),a=o>0,c=[n,0],l=Math.abs(o)>Wo,s=Te(n,6*Go);return Bt(t,e,s,i)}function ue(n,t,e,r){function u(r,u){return Math.abs(r[0]-n)0?0:3:Math.abs(r[0]-e)0?2:1:Math.abs(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.point,t.point)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}function a(u,i){var o=i[0]-u[0],a=i[1]-u[1],c=[0,1];return Math.abs(o)0&&(u[0]+=c[0]*o,u[1]+=c[0]*a),!0):!1}return function(c){function l(i){var o=u(i,-1),a=s([0===o||3===o?n:e,o>1?r:t]);return a}function s(n){for(var t=0,e=M.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=M[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&f(l,i,n)>0&&++t:i[1]<=r&&f(l,i,n)<0&&--t,l=i;return 0!==t}function f(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(e[0]-n[0])*(t[1]-n[1])}function h(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function g(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function p(n,t){g(n,t)&&c.point(n,t)}function d(){q.point=m,M&&M.push(x=[]),A=!0,k=!1,S=E=0/0}function v(){y&&(m(b,_),w&&k&&T.rejoin(),y.push(T.buffer())),q.point=p,k&&c.lineEnd()}function m(n,t){n=Math.max(-Wa,Math.min(Wa,n)),t=Math.max(-Wa,Math.min(Wa,t));var e=g(n,t);if(M&&x.push([n,t]),A)b=n,_=t,w=e,A=!1,e&&(c.lineStart(),c.point(n,t));else if(e&&k)c.point(n,t);else{var r=[S,E],u=[n,t];a(r,u)?(k||(c.lineStart(),c.point(r[0],r[1])),c.point(u[0],u[1]),e||c.lineEnd()):e&&(c.lineStart(),c.point(n,t))}S=n,E=t,k=e}var y,M,x,b,_,w,S,E,k,A,N=c,T=Jt(),q={point:p,lineStart:d,lineEnd:v,polygonStart:function(){c=T,y=[],M=[]},polygonEnd:function(){c=N,(y=mo.merge(y)).length?(c.polygonStart(),Xt(y,i,l,h,c),c.polygonEnd()):s([n,t])&&(c.polygonStart(),c.lineStart(),h(null,null,1,c),c.lineEnd(),c.polygonEnd()),y=M=x=null}};return q}}function ie(n,t,e){if(Math.abs(t)=n;var r=n/t;if(t>0){if(r>e[1])return!1;r>e[0]&&(e[0]=r)}else{if(rn&&(Ka=n),n>nc&&(nc=n),Qa>t&&(Qa=t),t>tc&&(tc=t)}function fe(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=he(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=he(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function he(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function ge(n,t){Fa+=n,Pa+=t,++Oa}function pe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);Ra+=o*(t+n)/2,Ya+=o*(e+r)/2,Ia+=o,ge(t=n,e=r)}var t,e;uc.point=function(r,u){uc.point=n,ge(t=r,e=u)}}function de(){uc.point=ge}function ve(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);Ra+=o*(r+n)/2,Ya+=o*(u+t)/2,Ia+=o,o=u*n-r*t,Ua+=o*(r+n),Za+=o*(u+t),Va+=3*o,ge(r=n,u=t)}var t,e,r,u;uc.point=function(i,o){uc.point=n,ge(t=r=i,e=u=o)},uc.lineEnd=function(){n(t,e)}}function me(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,2*Bo)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:c};return a}function ye(n){function t(t){function r(e,r){e=n(e,r),t.point(e[0],e[1])}function u(){M=0/0,S.point=o,t.lineStart()}function o(r,u){var o=Ct([r,u]),a=n(r,u);e(M,x,y,b,_,w,M=a[0],x=a[1],y=r,b=o[0],_=o[1],w=o[2],i,t),t.point(M,x)}function a(){S.point=r,t.lineEnd()}function c(){u(),S.point=l,S.lineEnd=s}function l(n,t){o(f=n,h=t),g=M,p=x,d=b,v=_,m=w,S.point=o}function s(){e(M,x,y,b,_,w,g,p,f,d,v,m,i,t),S.lineEnd=a,a()}var f,h,g,p,d,v,m,y,M,x,b,_,w,S={point:r,lineStart:u,lineEnd:a,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=u}};return S}function e(t,i,o,a,c,l,s,f,h,g,p,d,v,m){var y=s-t,M=f-i,x=y*y+M*M;if(x>4*r&&v--){var b=a+g,_=c+p,w=l+d,S=Math.sqrt(b*b+_*_+w*w),E=Math.asin(w/=S),k=Math.abs(Math.abs(w)-1)r||Math.abs((y*q+M*z)/x-.5)>.3||u>a*g+c*p+l*d)&&(e(t,i,o,a,c,l,N,T,k,b/=S,_/=S,w,v,m),m.point(N,T),e(N,T,k,b,_,w,s,f,h,g,p,d,v,m))}}var r=.5,u=Math.cos(30*Go),i=16;return t.precision=function(n){return arguments.length?(i=(r=n*n)>0&&16,t):Math.sqrt(r)},t}function Me(n){this.stream=n}function xe(n){var t=ye(function(t,e){return n([t*Ko,e*Ko])});return function(n){var e=new Me(n=t(n));return e.point=function(t,e){n.point(t*Go,e*Go)},e}}function be(n){return _e(function(){return n})()}function _e(n){function t(n){return n=a(n[0]*Go,n[1]*Go),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Ko,n[1]*Ko]}function r(){a=oe(o=Ee(m,y,M),i);var n=i(d,v);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=ye(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,d=0,v=0,m=0,y=0,M=0,x=$a,b=dt,_=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=we(o,x(f(b(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(x=null==n?(_=n,$a):re((_=+n)*Go),u()):_},t.clipExtent=function(n){return arguments.length?(w=n,b=n?ue(n[0][0],n[0][1],n[1][0],n[1][1]):dt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(d=n[0]%360*Go,v=n[1]%360*Go,r()):[d*Ko,v*Ko]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Go,y=n[1]%360*Go,M=n.length>2?n[2]%360*Go:0,r()):[m*Ko,y*Ko,M*Ko]},mo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function we(n,t){var e=new Me(t);return e.point=function(e,r){r=n(e*Go,r*Go),e=r[0],t.point(e>Bo?e-2*Bo:-Bo>e?e+2*Bo:e,r[1])},e}function Se(n,t){return[n,t]}function Ee(n,t,e){return n?t||e?oe(Ae(n),Ne(t,e)):Ae(n):t||e?Ne(t,e):Se}function ke(n){return function(t,e){return t+=n,[t>Bo?t-2*Bo:-Bo>t?t+2*Bo:t,e]}}function Ae(n){var t=ke(n);return t.invert=ke(-n),t}function Ne(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),O(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),O(s*r-a*u)]},e}function Te(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=qe(e,u),i=qe(e,i),(o>0?i>u:u>i)&&(u+=2*o*Bo)):(u=n+2*o*Bo,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=Pt([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function qe(n,t){var e=Ct(t);e[0]-=n,Ft(e);var r=P(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Wo)%(2*Math.PI)}function ze(n,t,e){var r=mo.range(n,t-Wo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function Ce(n,t,e){var r=mo.range(n,t-Wo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function De(n){return n.source}function je(n){return n.target}function Le(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(U(r-t)+u*o*U(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ko,Math.atan2(o,Math.sqrt(r*r+u*u))*Ko]}:function(){return[n*Ko,t*Ko]};return p.distance=h,p}function He(){function n(n,u){var i=Math.sin(u*=Go),o=Math.cos(u),a=Math.abs((n*=Go)-t),c=Math.cos(a);ic+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;oc.point=function(u,i){t=u*Go,e=Math.sin(i*=Go),r=Math.cos(i),oc.point=n},oc.lineEnd=function(){oc.point=oc.lineEnd=c}}function Fe(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function Pe(n,t){function e(n,t){var e=Math.abs(Math.abs(t)-Bo/2)1&&u.push("H",r[0]),u.join("")}function We(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function fr(n){return n.length<3?Xe(n):n[0]+nr(n,sr(n))}function hr(n,t,e,r){var u,i,o,a,c,l,s;return u=r[n],i=u[0],o=u[1],u=r[t],a=u[0],c=u[1],u=r[e],l=u[0],s=u[1],(s-o)*(a-i)-(c-o)*(l-i)>0}function gr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function pr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function dr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function vr(n,t){var e={list:n.map(function(n,t){return{index:t,x:n[0],y:n[1]}}).sort(function(n,t){return n.yt.y?1:n.xt.x?1:0}),bottomSite:null},r={list:[],leftEnd:null,rightEnd:null,init:function(){r.leftEnd=r.createHalfEdge(null,"l"),r.rightEnd=r.createHalfEdge(null,"l"),r.leftEnd.r=r.rightEnd,r.rightEnd.l=r.leftEnd,r.list.unshift(r.leftEnd,r.rightEnd)},createHalfEdge:function(n,t){return{edge:n,side:t,vertex:null,l:null,r:null}},insert:function(n,t){t.l=n,t.r=n.r,n.r.l=t,n.r=t},leftBound:function(n){var t=r.leftEnd;do t=t.r;while(t!=r.rightEnd&&u.rightOf(t,n));return t=t.l},del:function(n){n.l.r=n.r,n.r.l=n.l,n.edge=null},right:function(n){return n.r},left:function(n){return n.l},leftRegion:function(n){return null==n.edge?e.bottomSite:n.edge.region[n.side]},rightRegion:function(n){return null==n.edge?e.bottomSite:n.edge.region[mc[n.side]]}},u={bisect:function(n,t){var e={region:{l:n,r:t},ep:{l:null,r:null}},r=t.x-n.x,u=t.y-n.y,i=r>0?r:-r,o=u>0?u:-u;return e.c=n.x*r+n.y*u+.5*(r*r+u*u),i>o?(e.a=1,e.b=u/r,e.c/=r):(e.b=1,e.a=r/u,e.c/=u),e},intersect:function(n,t){var e=n.edge,r=t.edge;if(!e||!r||e.region.r==r.region.r)return null;var u=e.a*r.b-e.b*r.a;if(Math.abs(u)<1e-10)return null;var i,o,a=(e.c*r.b-r.c*e.b)/u,c=(r.c*e.a-e.c*r.a)/u,l=e.region.r,s=r.region.r;l.y=o.region.r.x;return f&&"l"===i.side||!f&&"r"===i.side?null:{x:a,y:c}},rightOf:function(n,t){var e=n.edge,r=e.region.r,u=t.x>r.x;if(u&&"l"===n.side)return 1;if(!u&&"r"===n.side)return 0;if(1===e.a){var i=t.y-r.y,o=t.x-r.x,a=0,c=0;if(!u&&e.b<0||u&&e.b>=0?c=a=i>=e.b*o:(c=t.x+t.y*e.b>e.c,e.b<0&&(c=!c),c||(a=1)),!a){var l=r.x-e.region.l.x;c=e.b*(o*o-i*i)h*h+g*g}return"l"===n.side?c:!c},endPoint:function(n,e,r){n.ep[e]=r,n.ep[mc[e]]&&t(n)},distance:function(n,t){var e=n.x-t.x,r=n.y-t.y;return Math.sqrt(e*e+r*r)}},i={list:[],insert:function(n,t,e){n.vertex=t,n.ystar=t.y+e;for(var r=0,u=i.list,o=u.length;o>r;r++){var a=u[r];if(!(n.ystar>a.ystar||n.ystar==a.ystar&&t.x>a.vertex.x))break}u.splice(r,0,n)},del:function(n){for(var t=0,e=i.list,r=e.length;r>t&&e[t]!=n;++t);e.splice(t,1)},empty:function(){return 0===i.list.length},nextEvent:function(n){for(var t=0,e=i.list,r=e.length;r>t;++t)if(e[t]==n)return e[t+1];return null},min:function(){var n=i.list[0];return{x:n.vertex.x,y:n.ystar}},extractMin:function(){return i.list.shift()}};r.init(),e.bottomSite=e.list.shift();for(var o,a,c,l,s,f,h,g,p,d,v,m,y,M=e.list.shift();;)if(i.empty()||(o=i.min()),M&&(i.empty()||M.yg.y&&(p=h,h=g,g=p,y="r"),m=u.bisect(h,g),f=r.createHalfEdge(m,y),r.insert(l,f),u.endPoint(m,mc[y],v),d=u.intersect(l,f),d&&(i.del(l),i.insert(l,d,u.distance(d,h))),d=u.intersect(f,s),d&&i.insert(f,d,u.distance(d,h))}for(a=r.right(r.leftEnd);a!=r.rightEnd;a=r.right(a))t(a.edge)}function mr(n){return n.x}function yr(n){return n.y}function Mr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function xr(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&xr(n,c[0],e,r,o,a),c[1]&&xr(n,c[1],o,r,u,a),c[2]&&xr(n,c[2],e,a,o,i),c[3]&&xr(n,c[3],o,a,u,i)}}function br(n,t){n=mo.rgb(n),t=mo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+ct(Math.round(e+i*n))+ct(Math.round(r+o*n))+ct(Math.round(u+a*n))}}function _r(n,t){var e,r={},u={};for(e in n)e in t?r[e]=Er(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function wr(n,t){return t-=n=+n,function(e){return n+t*e}}function Sr(n,t){var e,r,u,i,o,a=0,c=0,l=[],s=[];for(n+="",t+="",yc.lastIndex=0,r=0;e=yc.exec(t);++r)e.index&&l.push(t.substring(a,c=e.index)),s.push({i:l.length,x:e[0]}),l.push(null),a=yc.lastIndex;for(ar;++r)if(o=s[r],o.x==e[0]){if(o.i)if(null==l[o.i+1])for(l[o.i-1]+=o.x,l.splice(o.i,1),u=r+1;i>u;++u)s[u].i--;else for(l[o.i-1]+=o.x+l[o.i+1],l.splice(o.i,2),u=r+1;i>u;++u)s[u].i-=2;else if(null==l[o.i+1])l[o.i]=o.x;else for(l[o.i]=o.x+l[o.i+1],l.splice(o.i+1,1),u=r+1;i>u;++u)s[u].i--;s.splice(r,1),i--,r--}else o.x=wr(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=s.pop(),null==l[o.i+1]?l[o.i]=o.x:(l[o.i]=o.x+l[o.i+1],l.splice(o.i+1,1)),i--;return 1===l.length?null==l[0]?(o=s[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)l[(o=s[r]).i]=o.x(n);return l.join("")}}function Er(n,t){for(var e,r=mo.interpolators.length;--r>=0&&!(e=mo.interpolators[r](n,t)););return e}function kr(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Er(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Ar(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function Nr(n){return function(t){return 1-n(1-t)}}function Tr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function qr(n){return n*n}function zr(n){return n*n*n}function Cr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Dr(n){return function(t){return Math.pow(t,n)}}function jr(n){return 1-Math.cos(n*Bo/2)}function Lr(n){return Math.pow(2,10*(n-1))}function Hr(n){return 1-Math.sqrt(1-n*n)}function Fr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/(2*Bo)*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,10*-r)*Math.sin(2*(r-e)*Bo/t)}}function Pr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Or(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=mo.hcl(n),t=mo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return J(e+i*n,r+o*n,u+a*n)+""}}function Yr(n,t){n=mo.hsl(n),t=mo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return $(e+i*n,r+o*n,u+a*n)+""}}function Ir(n,t){n=mo.lab(n),t=mo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return Q(e+i*n,r+o*n,u+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Zr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Xr(t),u=Vr(t,e),i=Xr($r(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:wr(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:wr(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:wr(g[0],p[0])},{i:e-2,x:wr(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++ie;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function vu(n){return n.reduce(mu,0)}function mu(n,t){return n+t[1]}function yu(n,t){return Mu(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function Mu(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function xu(n){return[mo.min(n),mo.max(n)]}function bu(n,t){return n.parent==t.parent?1:2}function _u(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function wu(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function Su(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i0&&(n=r);return n}function Eu(n,t){return n.x-t.x}function ku(n,t){return t.x-n.x}function Au(n,t){return n.depth-t.depth}function Nu(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function qu(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function zu(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function Cu(n,t){return n.value-t.value}function Du(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function ju(n,t){n._pack_next=t,t._pack_prev=n}function Lu(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Hu(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(Fu),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],Ru(r,u,i),t(i),Du(r,i),r._pack_prev=i,Du(i,u),u=r._pack_next,o=3;l>o;o++){Ru(r,u,i=e[o]);var p=0,d=1,v=1;for(a=u._pack_next;a!==u;a=a._pack_next,d++)if(Lu(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!Lu(c,i);c=c._pack_prev,v++);p?(v>d||d==v&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(Pu)}}function Fu(n){n._pack_next=n._pack_prev=n}function Pu(n){delete n._pack_next,delete n._pack_prev}function Ou(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++iu&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function $u(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Bu(n){return n.rangeExtent?n.rangeExtent():$u(n.range())}function Wu(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Ju(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Gu(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Nc}function Ku(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Ku:Wu,c=r?Jr:Wr;return o=u(n,t,c,e),a=u(t,n,c,Er),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Ur)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return ri(n,t)},i.tickFormat=function(t,e){return ui(n,t,e)},i.nice=function(t){return ti(n,t),u()},i.copy=function(){return Qu(n,t,e,r)},u()}function ni(n,t){return mo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function ti(n,t){return Ju(n,Gu(ei(n,t)[2]))}function ei(n,t){null==t&&(t=10);var e=$u(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function ri(n,t){return mo.range.apply(mo,ei(n,t))}function ui(n,t,e){var r=-Math.floor(Math.log(ei(n,t)[2])/Math.LN10+.01);return mo.format(e?e.replace(Ea,function(n,t,e,u,i,o,a,c,l,s){return[t,e,u,i,o,a,c,l||"."+(r-2*("%"===s)),s].join("")}):",."+r+"f")}function ii(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Ju(r.map(u),e?Math:qc);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=$u(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Tc;arguments.length<2?t=Tc:"function"!=typeof t&&(t=mo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return ii(n.copy(),t,e,r)},ni(o,n)}function oi(n,t,e){function r(t){return n(u(t))}var u=ai(t),i=ai(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return ri(e,n)},r.tickFormat=function(n,t){return ui(e,n,t)},r.nice=function(n){return r.domain(ti(e,n))},r.exponent=function(o){return arguments.length?(u=ai(t=o),i=ai(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return oi(n.copy(),t,e)},ni(r,n)}function ai(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ci(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return mo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++ae?[0/0,0/0]:[e>0?u[e-1]:n[0],et?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return si(n,t,e)},u()}function fi(n,t){function e(e){return e>=e?t[mo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return fi(n,t)},e}function hi(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return ri(n,t)},t.tickFormat=function(t,e){return ui(n,t,e)},t.copy=function(){return hi(n)},t}function gi(n){return n.innerRadius}function pi(n){return n.outerRadius}function di(n){return n.startAngle}function vi(n){return n.endAngle}function mi(n){for(var t,e,r,u=-1,i=n.length;++ue?l():(i.active=e,o.event&&o.event.start.call(n,s,t),o.tween.forEach(function(e,r){(r=r.call(n,s,t))&&p.push(r)}),c(r)?1:(xt(c,0,a),void 0))}function c(r){if(i.active!==e)return l();for(var u=(r-h)/g,a=f(u),c=p.length;c>0;)p[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,s,t),l()):void 0}function l(){return--i.count?delete i[e]:delete n.__transition__,1}var s=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=[];return r>=h?u(r):(xt(u,h,a),void 0)},0,a)}}function Ti(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function qi(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function zi(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ci(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new Wc(e-1)),1),e}function i(n,e){return t(n=new Wc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{Wc=zi;var r=new zi;return r._=n,o(r,t,e)}finally{Wc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Di(n);return c.floor=c,c.round=Di(r),c.ceil=Di(u),c.offset=Di(i),c.range=a,n}function Di(n){return function(t,e){try{Wc=zi;var r=new zi;return r._=t,n(r,e)._}finally{Wc=Date}}}function ji(n){function t(t){for(var r,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=vl[o in pl?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function Hi(n){return new RegExp("^(?:"+n.map(mo.requote).join("|")+")","i")}function Fi(n){for(var t=new u,e=-1,r=n.length;++en?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Oi(n,t,e){al.lastIndex=0;var r=al.exec(t.substring(e));return r?(n.w=cl.get(r[0].toLowerCase()),e+r[0].length):-1}function Ri(n,t,e){il.lastIndex=0;var r=il.exec(t.substring(e));return r?(n.w=ol.get(r[0].toLowerCase()),e+r[0].length):-1}function Yi(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ii(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Ui(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function Zi(n,t,e){fl.lastIndex=0;var r=fl.exec(t.substring(e));return r?(n.m=hl.get(r[0].toLowerCase()),e+r[0].length):-1}function Vi(n,t,e){ll.lastIndex=0;var r=ll.exec(t.substring(e));return r?(n.m=sl.get(r[0].toLowerCase()),e+r[0].length):-1}function Xi(n,t,e){return Li(n,dl.c.toString(),t,e)}function $i(n,t,e){return Li(n,dl.x.toString(),t,e)}function Bi(n,t,e){return Li(n,dl.X.toString(),t,e)}function Wi(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Ji(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+2));return r?(n.y=Ki(+r[0]),e+r[0].length):-1}function Gi(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Ki(n){return n+(n>68?1900:2e3)}function Qi(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function no(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function to(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function eo(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ro(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function uo(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function io(n,t,e){ml.lastIndex=0;var r=ml.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function oo(n,t,e){var r=yl.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}function ao(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(Math.abs(t)/60),u=Math.abs(t)%60;return e+Pi(r,"0",2)+Pi(u,"0",2)}function co(n,t,e){gl.lastIndex=0;var r=gl.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function lo(n){function t(n){try{Wc=zi;var t=new Wc;return t._=n,e(t)}finally{Wc=Date}}var e=ji(n);return t.parse=function(n){try{Wc=zi;var t=e.parse(n);return t&&t._}finally{Wc=Date}},t.toString=e.toString,t}function so(n){return n.toISOString()}function fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=mo.bisect(xl,u);return i==xl.length?[t.year,ei(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/xl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=ho(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=ho(+t+1);return t}}:n))},r.ticks=function(n,t){var e=$u(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],ho(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return fo(n.copy(),t,e)},ni(r,n)}function ho(n){return new Date(n)}function go(n){return function(t){for(var e=n.length-1,r=n[e];!r[1](t);)r=n[--e];return r[0](t)}}function po(n){return JSON.parse(n.responseText)}function vo(n){var t=xo.createRange();return t.selectNode(xo.body),t.createContextualFragment(n.responseText)}var mo={version:"3.3.5"};Date.now||(Date.now=function(){return+new Date});var yo=[].slice,Mo=function(n){return yo.call(n)},xo=document,bo=xo.documentElement,_o=window;try{Mo(bo.childNodes)[0].nodeType}catch(wo){Mo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{xo.createElement("div").style.setProperty("opacity",0,"")}catch(So){var Eo=_o.Element.prototype,ko=Eo.setAttribute,Ao=Eo.setAttributeNS,No=_o.CSSStyleDeclaration.prototype,To=No.setProperty;Eo.setAttribute=function(n,t){ko.call(this,n,t+"")},Eo.setAttributeNS=function(n,t,e){Ao.call(this,n,t,e+"")},No.setProperty=function(n,t,e){To.call(this,n,t+"",e)}}mo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},mo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},mo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ur&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r)}return e},mo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ue&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ue&&(e=r)}return e},mo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=e);)e=u=void 0;for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=e);)e=void 0;for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},mo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i1&&(t=t.map(e)),t=t.filter(n),t.length?mo.quantile(t.sort(mo.ascending),.5):void 0},mo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)r;){var i=r+u>>>1;er?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},mo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=mo.min(arguments,t),r=new Array(e);++nr)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var l,s,f,h,g=-1,p=a.length,d=o[c++],v=new u;++g=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(mo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},mo.set=function(n){var t=new i;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(i,{has:function(n){return zo+n in this},add:function(n){return this[zo+n]=!0,n},remove:function(n){return n=zo+n,n in this&&delete this[n]},values:function(){var n=[];return this.forEach(function(t){n.push(t)}),n},forEach:function(n){for(var t in this)t.charCodeAt(0)===Co&&n.call(this,t.substring(1))}}),mo.behavior={},mo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},mo.event=null,mo.requote=function(n){return n.replace(jo,"\\$&")};var jo=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,Lo={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ho=function(n,t){return t.querySelector(n)},Fo=function(n,t){return t.querySelectorAll(n)},Po=bo[a(bo,"matchesSelector")],Oo=function(n,t){return Po.call(n,t)};"function"==typeof Sizzle&&(Ho=function(n,t){return Sizzle(n,t)[0]||null},Fo=function(n,t){return Sizzle.uniqueSort(Sizzle(n,t))},Oo=Sizzle.matchesSelector),mo.selection=function(){return Uo};var Ro=mo.selection.prototype=[];Ro.select=function(n){var t,e,r,u,i=[];n=d(n);for(var o=-1,a=this.length;++o=0&&(e=n.substring(0,t),n=n.substring(t+1)),Yo.hasOwnProperty(e)?{space:Yo[e],local:n}:n}},Ro.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=mo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(m(t,n[t]));return this}return this.each(m(n,t))},Ro.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=n.trim().split(/^|\s+/g)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(_(e,n[e],t));return this}if(2>r)return _o.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(_(n,t,e))},Ro.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(w(t,n[t]));return this}return this.each(w(n,t))},Ro.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Ro.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Ro.append=function(n){return n=S(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Ro.insert=function(n,t){return n=S(n),t=d(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments))})},Ro.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},Ro.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),d=new Array(a);if(t){var v,m=new u,y=new u,M=[];for(r=-1;++rr;++r)p[r]=E(e[r]);for(;a>r;++r)d[r]=n[r]}p.update=g,p.parentNode=g.parentNode=d.parentNode=n.parentNode,c.push(p),l.push(g),s.push(d)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++oi;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a)&&t.push(r)}return p(u)},Ro.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},Ro.sort=function(n){n=A.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},Ro.size=function(){var n=0;return this.each(function(){++n}),n};var Io=[];mo.selection.enter=T,mo.selection.enter.prototype=Io,Io.append=Ro.append,Io.empty=Ro.empty,Io.node=Ro.node,Io.call=Ro.call,Io.size=Ro.size,Io.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(C(n,t,e))};var Zo=mo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Zo.forEach(function(n){"on"+n in xo&&Zo.remove(n)});var Vo=a(bo.style,"userSelect"),Xo=0;mo.mouse=function(n){return H(n,h())};var $o=/WebKit/.test(_o.navigator.userAgent)?-1:0;mo.touches=function(n,t){return arguments.length<2&&(t=h().touches),t?Mo(t).map(function(t){var e=H(n,t);return e.identifier=t.identifier,e}):[]},mo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return mo.event.changedTouches[0].identifier}function e(n,t){return mo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(s,g),e=n[0]-d[0],r=n[1]-d[1];v|=e|r,d=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(v&&mo.event.target===h),f({type:"dragend"})}var c,l=this,s=l.parentNode,f=u.of(l,arguments),h=mo.event.target,g=n(),p=null==g?"drag":"drag-"+g,d=t(s,g),v=0,m=mo.select(_o).on(e+"."+p,o).on(r+"."+p,a),y=L();i?(c=i.apply(l,arguments),c=[c.x-d[0],c.y-d[1]]):c=[0,0],f({type:"dragstart"})}}var u=g(n,"drag","dragstart","dragend"),i=null,o=r(c,mo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},mo.rebind(n,u,"on")};var Bo=Math.PI,Wo=1e-6,Jo=Wo*Wo,Go=Bo/180,Ko=180/Bo,Qo=Math.SQRT2,na=2,ta=4;mo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Y(d),o=i/(na*h)*(e*I(Qo*t+d)-R(d));return[r+o*l,u+o*s,i*e/Y(Qo*t+d)]}return[r+n*l,u+n*s,i*Math.exp(Qo*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+ta*f)/(2*i*na*h),p=(c*c-i*i-ta*f)/(2*c*na*h),d=Math.log(Math.sqrt(g*g+1)-g),v=Math.log(Math.sqrt(p*p+1)-p),m=v-d,y=(m||Math.log(c/i))/Qo;return e.duration=1e3*y,e},mo.behavior.zoom=function(){function n(n){n.on(A,l).on(ua+".zoom",h).on(N,p).on("dblclick.zoom",d).on(q,s)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(k[0],Math.min(k[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){b&&b.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-S.y)/S.k}).map(_.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function l(){function n(){s=1,u(mo.mouse(r),h),a(i)}function e(){f.on(N,_o===r?p:null).on(T,null),g(s&&mo.event.target===l),c(i)}var r=this,i=C.of(r,arguments),l=mo.event.target,s=0,f=mo.select(_o).on(N,n).on(T,e),h=t(mo.mouse(r)),g=L();z.call(r),o(i)}function s(){function n(){var n=mo.touches(p);return g=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=mo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-M){var l=o[0],s=v[l.identifier];r(2*S.k),u(l,s),f(),a(d)}M=c}else if(o.length>1){var l=o[0],h=o[1],g=l[0]-h[0],p=l[1]-h[1];m=g*g+p*p}}function i(){for(var n,t,e,i,o=mo.touches(p),c=0,l=o.length;l>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*g)}M=null,u(n,t),a(d)}function h(){if(mo.event.touches.length){for(var t=mo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}_.on(x,null).on(b,null),w.on(A,l).on(q,s),E(),c(d)}var g,p=this,d=C.of(p,arguments),v={},m=0,y=mo.event.changedTouches[0].identifier,x="touchmove.zoom-"+y,b="touchend.zoom-"+y,_=mo.select(_o).on(x,i).on(b,h),w=mo.select(p).on(A,null).on(q,e),E=L();z.call(p),e(),o(d)}function h(){var n=C.of(this,arguments);y?clearTimeout(y):(z.call(this),o(n)),y=setTimeout(function(){y=null,c(n)},50),f();var e=m||mo.mouse(this);v||(v=t(e)),r(Math.pow(2,.002*ea())*S.k),u(e,v),a(n)}function p(){v=null}function d(){var n=C.of(this,arguments),e=mo.mouse(this),i=t(e),l=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,mo.event.shiftKey?Math.ceil(l)-1:Math.floor(l)+1)),u(e,i),a(n),c(n)}var v,m,y,M,x,b,_,w,S={x:0,y:0,k:1},E=[960,500],k=ra,A="mousedown.zoom",N="mousemove.zoom",T="mouseup.zoom",q="touchstart.zoom",C=g(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=C.of(this,arguments),t=S;Pc?mo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=e/2,i=r/2,o=mo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(k=null==t?ra:[+t[0],+t[1]],n):k},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.x=function(t){return arguments.length?(b=t,x=t.copy(),S={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),S={x:0,y:0,k:1},n):w},mo.rebind(n,C,"on")};var ea,ra=[0,1/0],ua="onwheel"in xo?(ea=function(){return-mo.event.deltaY*(mo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in xo?(ea=function(){return mo.event.wheelDelta},"mousewheel"):(ea=function(){return-mo.event.detail},"MozMousePixelScroll");Z.prototype.toString=function(){return this.rgb()+""},mo.hsl=function(n,t,e){return 1===arguments.length?n instanceof X?V(n.h,n.s,n.l):lt(""+n,st,V):V(+n,+t,+e)};var ia=X.prototype=new Z;ia.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),V(this.h,this.s,this.l/n)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),V(this.h,this.s,n*this.l)},ia.rgb=function(){return $(this.h,this.s,this.l)},mo.hcl=function(n,t,e){return 1===arguments.length?n instanceof W?B(n.h,n.c,n.l):n instanceof K?nt(n.l,n.a,n.b):nt((n=ft((n=mo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):B(+n,+t,+e)};var oa=W.prototype=new Z;oa.brighter=function(n){return B(this.h,this.c,Math.min(100,this.l+aa*(arguments.length?n:1)))},oa.darker=function(n){return B(this.h,this.c,Math.max(0,this.l-aa*(arguments.length?n:1)))},oa.rgb=function(){return J(this.h,this.c,this.l).rgb()},mo.lab=function(n,t,e){return 1===arguments.length?n instanceof K?G(n.l,n.a,n.b):n instanceof W?J(n.l,n.c,n.h):ft((n=mo.rgb(n)).r,n.g,n.b):G(+n,+t,+e)};var aa=18,ca=.95047,la=1,sa=1.08883,fa=K.prototype=new Z;fa.brighter=function(n){return G(Math.min(100,this.l+aa*(arguments.length?n:1)),this.a,this.b)},fa.darker=function(n){return G(Math.max(0,this.l-aa*(arguments.length?n:1)),this.a,this.b)},fa.rgb=function(){return Q(this.l,this.a,this.b)},mo.rgb=function(n,t,e){return 1===arguments.length?n instanceof at?ot(n.r,n.g,n.b):lt(""+n,ot,$):ot(~~n,~~t,~~e)};var ha=at.prototype=new Z;ha.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),ot(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):ot(u,u,u)},ha.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),ot(~~(n*this.r),~~(n*this.g),~~(n*this.b))},ha.hsl=function(){return st(this.r,this.g,this.b)},ha.toString=function(){return"#"+ct(this.r)+ct(this.g)+ct(this.b)};var ga=mo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ga.forEach(function(n,t){ga.set(n,ut(t))}),mo.functor=pt,mo.xhr=vt(dt),mo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=mo.xhr(n,t,i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o.row(e)}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function o(t){return t.map(a).join(n)}function a(n){return c.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var c=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=c)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==l)continue;return n.substring(t,s-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],c=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new i,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(a).join(n)].concat(t.map(function(t){return u.map(function(n){return a(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(o).join("\n")},e},mo.csv=mo.dsv(",","text/csv"),mo.tsv=mo.dsv(" ","text/tab-separated-values");var pa,da,va,ma,ya,Ma=_o[a(_o,"requestAnimationFrame")]||function(n){setTimeout(n,17)};mo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={callback:n,time:u,next:null};da?da.next=i:pa=i,da=i,va||(ma=clearTimeout(ma),va=1,Ma(Mt))},mo.timer.flush=function(){bt(),_t()};var xa=".",ba=",",_a=[3,3],wa="$",Sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(wt);mo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=mo.round(n,St(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Sa[8+e/3]},mo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)},mo.format=function(n){var t=Ea.exec(n),e=t[1]||" ",r=t[2]||">",u=t[3]||"",i=t[4]||"",o=t[5],a=+t[6],c=t[7],l=t[8],s=t[9],f=1,h="",g=!1;switch(l&&(l=+l.substring(1)),(o||"0"===e&&"="===r)&&(o=e="0",r="=",c&&(a-=Math.floor((a-1)/4))),s){case"n":c=!0,s="g";break;case"%":f=100,h="%",s="f";break;case"p":f=100,h="%",s="r";break;case"b":case"o":case"x":case"X":"#"===i&&(i="0"+s.toLowerCase());case"c":case"d":g=!0,l=0;break;case"s":f=-1,s="r"}"#"===i?i="":"$"===i&&(i=wa),"r"!=s||l||(s="g"),null!=l&&("g"==s?l=Math.max(1,Math.min(21,l)):("e"==s||"f"==s)&&(l=Math.max(0,Math.min(20,l)))),s=ka.get(s)||Et;var p=o&&c;return function(n){if(g&&n%1)return"";var t=0>n||0===n&&0>1/n?(n=-n,"-"):u;if(0>f){var d=mo.formatPrefix(n,l);n=d.scale(n),h=d.symbol}else n*=f;n=s(n,l);var v=n.lastIndexOf("."),m=0>v?n:n.substring(0,v),y=0>v?"":xa+n.substring(v+1);!o&&c&&(m=Aa(m));var M=i.length+m.length+y.length+(p?0:t.length),x=a>M?new Array(M=a-M+1).join(e):"";return p&&(m=Aa(x+m)),t+=i,n=m+y,("<"===r?t+n+x:">"===r?x+t+n:"^"===r?x.substring(0,M>>=1)+t+n+x.substring(M):t+(p?n:x+n))+h}};var Ea=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,ka=mo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=mo.round(n,St(n,t))).toFixed(Math.max(0,Math.min(20,St(n*(1+1e-15),t))))}}),Aa=dt;if(_a){var Na=_a.length;Aa=function(n){for(var t=n.length,e=[],r=0,u=_a[0];t>0&&u>0;)e.push(n.substring(t-=u,t+u)),u=_a[r=(r+1)%Na];return e.reverse().join(ba)}}mo.geo={},kt.prototype={s:0,t:0,add:function(n){At(n,this.t,Ta),At(Ta.s,this.s,this),this.s?this.t+=Ta.t:this.s=Ta.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var Ta=new kt;mo.geo.stream=function(n,t){n&&qa.hasOwnProperty(n.type)?qa[n.type](n,t):Nt(n,t)};var qa={Feature:function(n,t){Nt(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Bo+n:n,ja.lineStart=ja.lineEnd=ja.point=c}};mo.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=Ct([t*Go,e*Go]);if(m){var u=jt(m,r),i=[u[1],-u[0],0],o=jt(i,u);Ft(o),o=Pt(o);var c=t-p,l=c>0?1:-1,d=o[0]*Ko*l,v=Math.abs(c)>180;if(v^(d>l*p&&l*t>d)){var y=o[1]*Ko;y>g&&(g=y)}else if(d=(d+360)%360-180,v^(d>l*p&&l*t>d)){var y=-o[1]*Ko;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);v?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=Math.abs(r)>180?r+(r>0?360:-360):r}else d=n,v=e;ja.point(n,e),t(n,e)}function i(){ja.lineStart()}function o(){u(d,v),ja.lineEnd(),Math.abs(y)>Wo&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nDa?(s=-(h=180),f=-(g=90)):y>Wo?g=90:-Wo>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],mo.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),mo.geo.centroid=function(n){La=Ha=Fa=Pa=Oa=Ra=Ya=Ia=Ua=Za=Va=0,mo.geo.stream(n,Xa);var t=Ua,e=Za,r=Va,u=t*t+e*e+r*r;return Jo>u&&(t=Ra,e=Ya,r=Ia,Wo>Ha&&(t=Fa,e=Pa,r=Oa),u=t*t+e*e+r*r,Jo>u)?[0/0,0/0]:[Math.atan2(e,t)*Ko,O(r/Math.sqrt(u))*Ko]};var La,Ha,Fa,Pa,Oa,Ra,Ya,Ia,Ua,Za,Va,Xa={sphere:c,point:Rt,lineStart:It,lineEnd:Ut,polygonStart:function(){Xa.lineStart=Zt},polygonEnd:function(){Xa.lineStart=It}},$a=Bt(Vt,Qt,te,ee),Ba=[-Bo,0],Wa=1e9;mo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=ue(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(mo.geo.conicEqualArea=function(){return ae(ce)}).raw=ce,mo.geo.albers=function(){return mo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},mo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=mo.geo.albers(),o=mo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=mo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Wo,f+.12*l+Wo],[s-.214*l-Wo,f+.234*l-Wo]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Wo,f+.166*l+Wo],[s-.115*l-Wo,f+.234*l-Wo]]).stream(c).point,n},n.scale(1070)};var Ja,Ga,Ka,Qa,nc,tc,ec={point:c,lineStart:c,lineEnd:c,polygonStart:function(){Ga=0,ec.lineStart=le},polygonEnd:function(){ec.lineStart=ec.lineEnd=ec.point=c,Ja+=Math.abs(Ga/2)}},rc={point:se,lineStart:c,lineEnd:c,polygonStart:c,polygonEnd:c},uc={point:ge,lineStart:pe,lineEnd:de,polygonStart:function(){uc.lineStart=ve},polygonEnd:function(){uc.point=ge,uc.lineStart=pe,uc.lineEnd=de}};mo.geo.transform=function(n){return{stream:function(t){var e=new Me(t);for(var r in n)e[r]=n[r];return e}}},Me.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},mo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),mo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ja=0,mo.geo.stream(n,u(ec)),Ja},n.centroid=function(n){return Fa=Pa=Oa=Ra=Ya=Ia=Ua=Za=Va=0,mo.geo.stream(n,u(uc)),Va?[Ua/Va,Za/Va]:Ia?[Ra/Ia,Ya/Ia]:Oa?[Fa/Oa,Pa/Oa]:[0/0,0/0]},n.bounds=function(n){return nc=tc=-(Ka=Qa=1/0),mo.geo.stream(n,u(rc)),[[Ka,Qa],[nc,tc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||xe(n):dt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new fe:new me(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(mo.geo.albersUsa()).context(null)},mo.geo.projection=be,mo.geo.projectionMutator=_e,(mo.geo.equirectangular=function(){return be(Se)}).raw=Se.invert=Se,mo.geo.rotation=function(n){function t(t){return t=n(t[0]*Go,t[1]*Go),t[0]*=Ko,t[1]*=Ko,t}return n=Ee(n[0]%360*Go,n[1]*Go,n.length>2?n[2]*Go:0),t.invert=function(t){return t=n.invert(t[0]*Go,t[1]*Go),t[0]*=Ko,t[1]*=Ko,t},t},mo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=Ee(-n[0]*Go,-n[1]*Go,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ko,n[1]*=Ko}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=Te((t=+r)*Go,u*Go),n):t},n.precision=function(r){return arguments.length?(e=Te(t*Go,(u=+r)*Go),n):u},n.angle(90)},mo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Go,u=n[1]*Go,i=t[1]*Go,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},mo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return mo.range(Math.ceil(i/v)*v,u,v).map(h).concat(mo.range(Math.ceil(l/m)*m,c,m).map(g)).concat(mo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return Math.abs(n%v)>Wo -}).map(s)).concat(mo.range(Math.ceil(a/d)*d,o,d).filter(function(n){return Math.abs(n%m)>Wo}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,d=p,v=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(v=+t[0],m=+t[1],n):[v,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],d=+t[1],n):[p,d]},n.precision=function(t){return arguments.length?(y=+t,s=ze(a,o,90),f=Ce(r,e,y),h=ze(l,c,90),g=Ce(i,u,y),n):y},n.majorExtent([[-180,-90+Wo],[180,90-Wo]]).minorExtent([[-180,-80-Wo],[180,80+Wo]])},mo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=De,u=je;return n.distance=function(){return mo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},mo.geo.interpolate=function(n,t){return Le(n[0]*Go,n[1]*Go,t[0]*Go,t[1]*Go)},mo.geo.length=function(n){return ic=0,mo.geo.stream(n,oc),ic};var ic,oc={sphere:c,point:c,lineStart:He,lineEnd:c,polygonStart:c,polygonEnd:c},ac=Fe(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(mo.geo.azimuthalEqualArea=function(){return be(ac)}).raw=ac;var cc=Fe(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},dt);(mo.geo.azimuthalEquidistant=function(){return be(cc)}).raw=cc,(mo.geo.conicConformal=function(){return ae(Pe)}).raw=Pe,(mo.geo.conicEquidistant=function(){return ae(Oe)}).raw=Oe;var lc=Fe(function(n){return 1/n},Math.atan);(mo.geo.gnomonic=function(){return be(lc)}).raw=lc,Re.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Bo/2]},(mo.geo.mercator=function(){return Ye(Re)}).raw=Re;var sc=Fe(function(){return 1},Math.asin);(mo.geo.orthographic=function(){return be(sc)}).raw=sc;var fc=Fe(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(mo.geo.stereographic=function(){return be(fc)}).raw=fc,Ie.invert=function(n,t){return[Math.atan2(R(n),Math.cos(t)),O(Math.sin(t)/Y(n))]},(mo.geo.transverseMercator=function(){return Ye(Ie)}).raw=Ie,mo.geom={},mo.svg={},mo.svg.line=function(){return Ue(dt)};var hc=mo.map({linear:Xe,"linear-closed":$e,step:Be,"step-before":We,"step-after":Je,basis:er,"basis-open":rr,"basis-closed":ur,bundle:ir,cardinal:Qe,"cardinal-open":Ge,"cardinal-closed":Ke,monotone:fr});hc.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var gc=[0,2/3,1/3,0],pc=[0,1/3,2/3,0],dc=[0,1/6,2/3,1/6];mo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u,i,o,a,c,l,s,f,h,g,p,d=pt(e),v=pt(r),m=n.length,y=m-1,M=[],x=[],b=0;if(d===Ze&&r===Ve)t=n;else for(i=0,t=[];m>i;++i)t.push([+d.call(this,u=n[i],i),+v.call(this,u,i)]);for(i=1;m>i;++i)(t[i][1]i;++i)i!==b&&(c=t[i][1]-t[b][1],a=t[i][0]-t[b][0],M.push({angle:Math.atan2(c,a),index:i}));for(M.sort(function(n,t){return n.angle-t.angle}),g=M[0].angle,h=M[0].index,f=0,i=1;y>i;++i){if(o=M[i].index,g==M[i].angle){if(a=t[h][0]-t[b][0],c=t[h][1]-t[b][1],l=t[o][0]-t[b][0],s=t[o][1]-t[b][1],a*a+c*c>=l*l+s*s){M[i].index=-1;continue}M[f].index=-1}g=M[i].angle,f=i,h=o}for(x.push(b),i=0,o=0;2>i;++o)M[o].index>-1&&(x.push(M[o].index),i++);for(p=x.length;y>o;++o)if(!(M[o].index<0)){for(;!hr(x[p-2],x[p-1],M[o].index,t);)--p;x[p++]=M[o].index}var _=[];for(i=p-1;i>=0;--i)_.push(n[x[i]]);return _}var e=Ze,r=Ve;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},mo.geom.polygon=function(n){return Lo(n,vc),n};var vc=mo.geom.polygon.prototype=[];vc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++ta;a++)e.push([u,t[a],t[a+1]])}),e},mo.geom.voronoi=function(n){function t(n){var t,i,o,a=n.map(function(){return[]}),c=pt(e),l=pt(r),s=n.length,f=1e6;if(c===Ze&&l===Ve)t=n;else for(t=new Array(s),o=0;s>o;++o)t[o]=[+c.call(this,i=n[o],o),+l.call(this,i,o)];if(vr(t,function(n){var t,e,r,u,i,o;1===n.a&&n.b>=0?(t=n.ep.r,e=n.ep.l):(t=n.ep.l,e=n.ep.r),1===n.a?(i=t?t.y:-f,r=n.c-n.b*i,o=e?e.y:f,u=n.c-n.b*o):(r=t?t.x:-f,i=n.c-n.a*r,u=e?e.x:f,o=n.c-n.a*u);var c=[r,i],l=[u,o];a[n.region.l.index].push(c,l),a[n.region.r.index].push(c,l)}),a=a.map(function(n,e){var r=t[e][0],u=t[e][1],i=n.map(function(n){return Math.atan2(n[0]-r,n[1]-u)}),o=mo.range(n.length).sort(function(n,t){return i[n]-i[t]});return o.filter(function(n,t){return!t||i[n]-i[o[t-1]]>Wo}).map(function(t){return n[t]})}),a.forEach(function(n,e){var r=n.length;if(!r)return n.push([-f,-f],[-f,f],[f,f],[f,-f]);if(!(r>2)){var u=t[e],i=n[0],o=n[1],a=u[0],c=u[1],l=i[0],s=i[1],h=o[0],g=o[1],p=Math.abs(h-l),d=g-s;if(Math.abs(d)c?-f:f;n.push([-f,v],[f,v])}else if(Wo>p){var m=l>a?-f:f;n.push([m,-f],[m,f])}else{var v=(l-a)*(g-s)>(h-l)*(s-c)?f:-f,y=Math.abs(d)-p;Math.abs(y)d?v:-v,v]):(y>0&&(v*=-1),n.push([-f,v],[f,v]))}}}),u)for(o=0;s>o;++o)u.clip(a[o]);for(o=0;s>o;++o)a[o].point=n[o];return a}var e=Ze,r=Ve,u=null;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.clipExtent=function(n){if(!arguments.length)return u&&[u[0],u[2]];if(null==n)u=null;else{var e=+n[0][0],r=+n[0][1],i=+n[1][0],o=+n[1][1];u=mo.geom.polygon([[e,r],[e,o],[i,o],[i,r]])}return t},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):u&&u[2]},t.links=function(n){var t,u,i,o=n.map(function(){return[]}),a=[],c=pt(e),l=pt(r),s=n.length;if(c===Ze&&l===Ve)t=n;else for(t=new Array(s),i=0;s>i;++i)t[i]=[+c.call(this,u=n[i],i),+l.call(this,u,i)];return vr(t,function(t){var e=t.region.l.index,r=t.region.r.index;o[e][r]||(o[e][r]=o[r][e]=!0,a.push({source:n[e],target:n[r]}))}),a},t.triangles=function(n){if(e===Ze&&r===Ve)return mo.geom.delaunay(n);for(var t,u=new Array(c),i=pt(e),o=pt(r),a=-1,c=n.length;++a=l,h=r>=s,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=Mr()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,d,v,m,y,M=pt(a),x=pt(c);if(null!=t)d=t,v=e,m=r,y=u;else if(m=y=-(d=v=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);d>b&&(d=b),v>_&&(v=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-d,S=y-v;w>S?y=v+w:m=d+S;var E=Mr();if(E.add=function(n){i(E,n,+M(n,++g),+x(n,g),d,v,m,y)},E.visit=function(n){xr(n,E,d,v,m,y)},g=-1,null==t){for(;++g=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=xc.get(e)||Mc,r=bc.get(r)||dt,Ar(r(e.apply(null,Array.prototype.slice.call(arguments,1))))},mo.interpolateHcl=Rr,mo.interpolateHsl=Yr,mo.interpolateLab=Ir,mo.interpolateRound=Ur,mo.transform=function(n){var t=xo.createElementNS(mo.ns.prefix.svg,"g");return(mo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Zr(e?e.matrix:_c)})(n)},Zr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var _c={a:1,b:0,c:0,d:1,e:0,f:0};mo.interpolateTransform=Br,mo.layout={},mo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e(u-e)*a){var c=t.charge*a*a;return n.px-=i*c,n.py-=o*c,!0}if(t.point&&isFinite(a)){var c=t.pointCharge*a*a;n.px-=i*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=mo.event.x,n.py=mo.event.y,a.resume()}var e,r,u,i,o,a={},c=mo.dispatch("start","tick","end"),l=[1,1],s=.9,f=wc,h=Sc,g=-30,p=.1,d=.8,v=[],m=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,d,y,M,x,b=v.length,_=m.length;for(e=0;_>e;++e)a=m[e],f=a.source,h=a.target,M=h.x-f.x,x=h.y-f.y,(d=M*M+x*x)&&(d=r*i[e]*((d=Math.sqrt(d))-u[e])/d,M*=d,x*=d,h.x-=M*(y=f.weight/(h.weight+f.weight)),h.y-=x*y,f.x+=M*(y=1-y),f.y+=x*y);if((y=r*p)&&(M=l[0]/2,x=l[1]/2,e=-1,y))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),mo.timer(a.tick)),a):r},a.start=function(){function n(n,r){for(var u,i=t(e),o=-1,a=i.length;++or;++r)c[r]=[];for(r=0;d>r;++r){var n=m[r];c[n.source.index].push(n.target),c[n.target.index].push(n.source)}}return c[e]}var e,r,c,s,p=v.length,d=m.length,y=l[0],M=l[1];for(e=0;p>e;++e)(s=v[e]).index=e,s.weight=0;for(e=0;d>e;++e)s=m[e],"number"==typeof s.source&&(s.source=v[s.source]),"number"==typeof s.target&&(s.target=v[s.target]),++s.source.weight,++s.target.weight;for(e=0;p>e;++e)s=v[e],isNaN(s.x)&&(s.x=n("x",y)),isNaN(s.y)&&(s.y=n("y",M)),isNaN(s.px)&&(s.px=s.x),isNaN(s.py)&&(s.py=s.y);if(u=[],"function"==typeof f)for(e=0;d>e;++e)u[e]=+f.call(this,m[e],e);else for(e=0;d>e;++e)u[e]=f;if(i=[],"function"==typeof h)for(e=0;d>e;++e)i[e]=+h.call(this,m[e],e);else for(e=0;d>e;++e)i[e]=h;if(o=[],"function"==typeof g)for(e=0;p>e;++e)o[e]=+g.call(this,v[e],e);else for(e=0;p>e;++e)o[e]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=mo.behavior.drag().origin(dt).on("dragstart.force",nu).on("drag.force",t).on("dragend.force",tu)),arguments.length?(this.on("mouseover.force",eu).on("mouseout.force",ru).call(e),void 0):e},mo.rebind(a,c,"on")};var wc=20,Sc=1;mo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(l=c.length)){for(var l,s,f=-1,h=t.children=[],g=0,p=o+1;++fg;++g)for(u.call(n,l[0][g],p=d[g],s[0][g][1]),h=1;v>h;++h)u.call(n,l[h][g],p+=s[h-1][g][1],s[h][g][1]);return a}var t=dt,e=gu,r=pu,u=hu,i=su,o=fu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:kc.get(t)||gu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:Ac.get(t)||pu,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var kc=mo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(du),i=n.map(vu),o=mo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return mo.range(n.length).reverse()},"default":gu}),Ac=mo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:pu});mo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[mo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=xu,u=yu;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=pt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return Mu(n,t)}:pt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},mo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,l,s=r[0],f=s,h=-1;++h0&&(qu(zu(a,n,r),n,u),l+=u,s+=u),f+=a._tree.mod,l+=i._tree.mod,h+=c._tree.mod,s+=o._tree.mod;a&&!wu(o)&&(o._tree.thread=a,o._tree.mod+=f-s),i&&!_u(c)&&(c._tree.thread=i,c._tree.mod+=l-h,r=n)}return r}var l=t.call(this,n,i),s=l[0];Nu(s,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(s),a(s,-s._tree.prelim);var f=Su(s,ku),h=Su(s,Eu),g=Su(s,Au),p=f.x-e(f,h)/2,d=h.x+e(h,f)/2,v=g.depth||1;return Nu(s,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(d-p)*r[0],n.y=n.depth/v*r[1],delete n._tree}),l}var t=mo.layout.hierarchy().sort(null).value(null),e=bu,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},iu(n,t)},mo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Nu(a,function(n){n.r=+s(n.value)}),Nu(a,Hu),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Nu(a,function(n){n.r+=f}),Nu(a,Hu),Nu(a,function(n){n.r-=f})}return Ou(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=mo.layout.hierarchy().sort(Cu),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},iu(n,e)},mo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Nu(c,function(n){var t=n.children;t&&t.length?(n.x=Iu(t),n.y=Yu(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Uu(c),f=Zu(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Nu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=mo.layout.hierarchy().sort(null).value(null),e=bu,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},iu(n,t)},mo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,d="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,d))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,d,l,!1),d=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,d,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=mo.random.normal.apply(mo,arguments);return function(){return Math.exp(n())}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t/n}}},mo.scale={};var Nc={floor:dt,ceil:dt};mo.scale.linear=function(){return Qu([0,1],[0,1],Er,!1)},mo.scale.log=function(){return ii(mo.scale.linear().domain([0,1]),10,!0,[1,10])};var Tc=mo.format(".0e"),qc={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};mo.scale.pow=function(){return oi(mo.scale.linear(),1,[0,1])},mo.scale.sqrt=function(){return mo.scale.pow().exponent(.5)},mo.scale.ordinal=function(){return ci([],{t:"range",a:[[]]})},mo.scale.category10=function(){return mo.scale.ordinal().range(zc)},mo.scale.category20=function(){return mo.scale.ordinal().range(Cc)},mo.scale.category20b=function(){return mo.scale.ordinal().range(Dc)},mo.scale.category20c=function(){return mo.scale.ordinal().range(jc)};var zc=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(it),Cc=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(it),Dc=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(it),jc=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(it);mo.scale.quantile=function(){return li([],[])},mo.scale.quantize=function(){return si(0,1,[0,1])},mo.scale.threshold=function(){return fi([.5],[0,1])},mo.scale.identity=function(){return hi([0,1])},mo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+Lc,a=u.apply(this,arguments)+Lc,c=(o>a&&(c=o,o=a,a=c),a-o),l=Bo>c?"0":"1",s=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=Hc?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*s+","+i*f+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+l+",0 "+n*s+","+n*f+"Z":"M"+i*s+","+i*f+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=gi,e=pi,r=di,u=vi;return n.innerRadius=function(e){return arguments.length?(t=pt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=pt(t),n):e},n.startAngle=function(t){return arguments.length?(r=pt(t),n):r},n.endAngle=function(t){return arguments.length?(u=pt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+Lc;return[Math.cos(i)*n,Math.sin(i)*n]},n};var Lc=-Bo/2,Hc=2*Bo-1e-6;mo.svg.line.radial=function(){var n=Ue(mi);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},We.reverse=Je,Je.reverse=We,mo.svg.area=function(){return yi(dt)},mo.svg.area.radial=function(){var n=yi(mi);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},mo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+Lc,s=l.call(n,u,r)+Lc;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Bo)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=De,o=je,a=Mi,c=di,l=vi;return n.radius=function(t){return arguments.length?(a=pt(t),n):a},n.source=function(t){return arguments.length?(i=pt(t),n):i},n.target=function(t){return arguments.length?(o=pt(t),n):o},n.startAngle=function(t){return arguments.length?(c=pt(t),n):c},n.endAngle=function(t){return arguments.length?(l=pt(t),n):l},n},mo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=De,e=je,r=xi;return n.source=function(e){return arguments.length?(t=pt(e),n):t},n.target=function(t){return arguments.length?(e=pt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},mo.svg.diagonal.radial=function(){var n=mo.svg.diagonal(),t=xi,e=n.projection;return n.projection=function(n){return arguments.length?e(bi(t=n)):t},n},mo.svg.symbol=function(){function n(n,r){return(Fc.get(t.call(this,n,r))||Si)(e.call(this,n,r))}var t=wi,e=_i;return n.type=function(e){return arguments.length?(t=pt(e),n):t},n.size=function(t){return arguments.length?(e=pt(t),n):e},n};var Fc=mo.map({circle:Si,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Yc)),e=t*Yc;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Rc),e=t*Rc/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Rc),e=t*Rc/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});mo.svg.symbolTypes=Fc.keys();var Pc,Oc,Rc=Math.sqrt(3),Yc=Math.tan(30*Go),Ic=[],Uc=0;Ic.call=Ro.call,Ic.empty=Ro.empty,Ic.node=Ro.node,Ic.size=Ro.size,mo.transition=function(n){return arguments.length?Pc?n.transition():n:Uo.transition()},mo.transition.prototype=Ic,Ic.select=function(n){var t,e,r,u=this.id,i=[];n=d(n);for(var o=-1,a=this.length;++oi;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a)&&t.push(r)}return Ei(u,this.id)},Ic.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):N(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ic.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n)) -})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Br:Er,a=mo.ns.qualify(n);return ki(this,"attr."+n,t,a.local?i:u)},Ic.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=mo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ic.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=_o.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=Er(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return ki(this,"style."+n,t,u)},Ic.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,_o.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ic.text=function(n){return ki(this,"text",n,Ai)},Ic.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ic.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=mo.ease.apply(mo,arguments)),N(this,function(e){e.__transition__[t].ease=n}))},Ic.delay=function(n){var t=this.id;return N(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ic.duration=function(n){var t=this.id;return N(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ic.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Oc,u=Pc;Pc=e,N(this,function(t,r,u){Oc=t.__transition__[e],n.call(t,t.__data__,r,u)}),Oc=r,Pc=u}else N(this,function(r){var u=r.__transition__[e];(u.event||(u.event=mo.dispatch("start","end"))).on(n,t)});return this},Ic.transition=function(){for(var n,t,e,r,u=this.id,i=++Uc,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],l=0,s=t.length;s>l;l++)(e=t[l])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Ni(e,l,i,r)),n.push(e)}return Ei(o,i)},mo.svg.axis=function(){function n(n){n.each(function(){var n,l=mo.select(this),s=null==c?e.ticks?e.ticks.apply(e,a):e.domain():c,f=null==t?e.tickFormat?e.tickFormat.apply(e,a):dt:t,h=l.selectAll(".tick").data(s,e),g=h.enter().insert("g",".domain").attr("class","tick").style("opacity",1e-6),p=mo.transition(h.exit()).style("opacity",1e-6).remove(),d=mo.transition(h).style("opacity",1),v=Bu(e),m=l.selectAll(".domain").data([0]),y=(m.enter().append("path").attr("class","domain"),mo.transition(m)),M=e.copy(),x=this.__chart__||M;this.__chart__=M,g.append("line"),g.append("text");var b=g.select("line"),_=d.select("line"),w=h.select("text").text(f),S=g.select("text"),E=d.select("text");switch(r){case"bottom":n=Ti,b.attr("y2",u),S.attr("y",Math.max(u,0)+o),_.attr("x2",0).attr("y2",u),E.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),y.attr("d","M"+v[0]+","+i+"V0H"+v[1]+"V"+i);break;case"top":n=Ti,b.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),_.attr("x2",0).attr("y2",-u),E.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),y.attr("d","M"+v[0]+","+-i+"V0H"+v[1]+"V"+-i);break;case"left":n=qi,b.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),_.attr("x2",-u).attr("y2",0),E.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),y.attr("d","M"+-i+","+v[0]+"H0V"+v[1]+"H"+-i);break;case"right":n=qi,b.attr("x2",u),S.attr("x",Math.max(u,0)+o),_.attr("x2",u).attr("y2",0),E.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),y.attr("d","M"+i+","+v[0]+"H0V"+v[1]+"H"+i)}if(e.rangeBand){var k=M.rangeBand()/2,A=function(n){return M(n)+k};g.call(n,A),d.call(n,A)}else g.call(n,x),d.call(n,M),p.call(n,M)})}var t,e=mo.scale.linear(),r=Zc,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Vc?t+"":Zc,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Zc="bottom",Vc={top:1,right:1,bottom:1,left:1};mo.svg.brush=function(){function n(i){i.each(function(){var i=mo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(v,dt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Xc[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var s,f=mo.transition(i),h=mo.transition(o);c&&(s=Bu(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Bu(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function r(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==mo.event.keyCode&&(N||(M=null,q[0]-=s[1],q[1]-=h[1],N=2),f())}function g(){32==mo.event.keyCode&&2==N&&(q[0]+=s[1],q[1]+=h[1],N=0,f())}function v(){var n=mo.mouse(b),u=!1;x&&(n[0]+=x[0],n[1]+=x[1]),N||(mo.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),q[0]=s[+(n[0]f?(u=r,r=f):u=f),g[0]!=r||g[1]!=u?(e?o=null:i=null,g[0]=r,g[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),mo.select("body").style("cursor",null),z.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),T(),w({type:"brushend"})}var M,x,b=this,_=mo.select(mo.event.target),w=a.of(b,arguments),S=mo.select(b),E=_.datum(),k=!/^(n|s)$/.test(E)&&c,A=!/^(e|w)$/.test(E)&&l,N=_.classed("extent"),T=L(),q=mo.mouse(b),z=mo.select(_o).on("keydown.brush",u).on("keyup.brush",g);if(mo.event.changedTouches?z.on("touchmove.brush",v).on("touchend.brush",y):z.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),N)q[0]=s[0]-q[0],q[1]=h[0]-q[1];else if(E){var C=+/w$/.test(E),D=+/^n/.test(E);x=[s[1-C]-q[0],h[1-D]-q[1]],q[0]=s[C],q[1]=h[D]}else mo.event.altKey&&(M=q.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),mo.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=g(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],h=[0,0],p=!0,d=!0,v=$c[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:h,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Pc?mo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=kr(s,t.x),r=kr(h,t.y);return i=o=null,function(u){s=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=$c[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,v=$c[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(p=!!t[0],d=!!t[1]):c?p=!!t:l&&(d=!!t),n):c&&l?[p,d]:c?p:l?d:null},n.extent=function(t){var e,r,u,a,f;return arguments.length?(c&&(e=t[0],r=t[1],l&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(f=e,e=r,r=f),(e!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(a)),u>a&&(f=u,u=a,a=f),(u!=h[0]||a!=h[1])&&(h=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(f=e,e=r,r=f))),l&&(o?(u=o[0],a=o[1]):(u=h[0],a=h[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(f=u,u=a,a=f))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&h[0]==h[1]},mo.rebind(n,a,"on")};var Xc={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},$c=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Bc=mo.time={},Wc=Date,Jc=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];zi.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){Gc.setUTCDate.apply(this._,arguments)},setDay:function(){Gc.setUTCDay.apply(this._,arguments)},setFullYear:function(){Gc.setUTCFullYear.apply(this._,arguments)},setHours:function(){Gc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){Gc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){Gc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){Gc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){Gc.setUTCSeconds.apply(this._,arguments)},setTime:function(){Gc.setTime.apply(this._,arguments)}};var Gc=Date.prototype,Kc="%a %b %e %X %Y",Qc="%m/%d/%Y",nl="%H:%M:%S",tl=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],el=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],rl=["January","February","March","April","May","June","July","August","September","October","November","December"],ul=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];Bc.year=Ci(function(n){return n=Bc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Bc.years=Bc.year.range,Bc.years.utc=Bc.year.utc.range,Bc.day=Ci(function(n){var t=new Wc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Bc.days=Bc.day.range,Bc.days.utc=Bc.day.utc.range,Bc.dayOfYear=function(n){var t=Bc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},Jc.forEach(function(n,t){n=n.toLowerCase(),t=7-t;var e=Bc[n]=Ci(function(n){return(n=Bc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Bc.year(n).getDay();return Math.floor((Bc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Bc[n+"s"]=e.range,Bc[n+"s"].utc=e.utc.range,Bc[n+"OfYear"]=function(n){var e=Bc.year(n).getDay();return Math.floor((Bc.dayOfYear(n)+(e+t)%7)/7)}}),Bc.week=Bc.sunday,Bc.weeks=Bc.sunday.range,Bc.weeks.utc=Bc.sunday.utc.range,Bc.weekOfYear=Bc.sundayOfYear,Bc.format=ji;var il=Hi(tl),ol=Fi(tl),al=Hi(el),cl=Fi(el),ll=Hi(rl),sl=Fi(rl),fl=Hi(ul),hl=Fi(ul),gl=/^%/,pl={"-":"",_:" ",0:"0"},dl={a:function(n){return el[n.getDay()]},A:function(n){return tl[n.getDay()]},b:function(n){return ul[n.getMonth()]},B:function(n){return rl[n.getMonth()]},c:ji(Kc),d:function(n,t){return Pi(n.getDate(),t,2)},e:function(n,t){return Pi(n.getDate(),t,2)},H:function(n,t){return Pi(n.getHours(),t,2)},I:function(n,t){return Pi(n.getHours()%12||12,t,2)},j:function(n,t){return Pi(1+Bc.dayOfYear(n),t,3)},L:function(n,t){return Pi(n.getMilliseconds(),t,3)},m:function(n,t){return Pi(n.getMonth()+1,t,2)},M:function(n,t){return Pi(n.getMinutes(),t,2)},p:function(n){return n.getHours()>=12?"PM":"AM"},S:function(n,t){return Pi(n.getSeconds(),t,2)},U:function(n,t){return Pi(Bc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Pi(Bc.mondayOfYear(n),t,2)},x:ji(Qc),X:ji(nl),y:function(n,t){return Pi(n.getFullYear()%100,t,2)},Y:function(n,t){return Pi(n.getFullYear()%1e4,t,4)},Z:ao,"%":function(){return"%"}},vl={a:Oi,A:Ri,b:Zi,B:Vi,c:Xi,d:no,e:no,H:eo,I:eo,j:to,L:io,m:Qi,M:ro,p:oo,S:uo,U:Ii,w:Yi,W:Ui,x:$i,X:Bi,y:Ji,Y:Wi,Z:Gi,"%":co},ml=/^\s*\d+/,yl=mo.map({am:0,pm:1});ji.utc=lo;var Ml=lo("%Y-%m-%dT%H:%M:%S.%LZ");ji.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?so:Ml,so.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},so.toString=Ml.toString,Bc.second=Ci(function(n){return new Wc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Bc.seconds=Bc.second.range,Bc.seconds.utc=Bc.second.utc.range,Bc.minute=Ci(function(n){return new Wc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Bc.minutes=Bc.minute.range,Bc.minutes.utc=Bc.minute.utc.range,Bc.hour=Ci(function(n){var t=n.getTimezoneOffset()/60;return new Wc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Bc.hours=Bc.hour.range,Bc.hours.utc=Bc.hour.utc.range,Bc.month=Ci(function(n){return n=Bc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Bc.months=Bc.month.range,Bc.months.utc=Bc.month.utc.range;var xl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],bl=[[Bc.second,1],[Bc.second,5],[Bc.second,15],[Bc.second,30],[Bc.minute,1],[Bc.minute,5],[Bc.minute,15],[Bc.minute,30],[Bc.hour,1],[Bc.hour,3],[Bc.hour,6],[Bc.hour,12],[Bc.day,1],[Bc.day,2],[Bc.week,1],[Bc.month,1],[Bc.month,3],[Bc.year,1]],_l=[[ji("%Y"),Vt],[ji("%B"),function(n){return n.getMonth()}],[ji("%b %d"),function(n){return 1!=n.getDate()}],[ji("%a %d"),function(n){return n.getDay()&&1!=n.getDate()}],[ji("%I %p"),function(n){return n.getHours()}],[ji("%I:%M"),function(n){return n.getMinutes()}],[ji(":%S"),function(n){return n.getSeconds()}],[ji(".%L"),function(n){return n.getMilliseconds()}]],wl=go(_l);bl.year=Bc.year,Bc.scale=function(){return fo(mo.scale.linear(),bl,wl)};var Sl={range:function(n,t,e){return mo.range(+n,+t,e).map(ho)}},El=bl.map(function(n){return[n[0].utc,n[1]]}),kl=[[lo("%Y"),Vt],[lo("%B"),function(n){return n.getUTCMonth()}],[lo("%b %d"),function(n){return 1!=n.getUTCDate()}],[lo("%a %d"),function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],[lo("%I %p"),function(n){return n.getUTCHours()}],[lo("%I:%M"),function(n){return n.getUTCMinutes()}],[lo(":%S"),function(n){return n.getUTCSeconds()}],[lo(".%L"),function(n){return n.getUTCMilliseconds()}]],Al=go(kl);return El.year=Bc.year.utc,Bc.scale.utc=function(){return fo(mo.scale.linear(),El,Al)},mo.text=vt(function(n){return n.responseText}),mo.json=function(n,t){return mt(n,"application/json",po,t)},mo.html=function(n,t){return mt(n,"text/html",vo,t)},mo.xml=vt(function(n){return n.responseXML}),mo}(); \ No newline at end of file diff --git a/d3.sublime-project b/d3.sublime-project new file mode 100644 index 00000000000000..772dfa530160a4 --- /dev/null +++ b/d3.sublime-project @@ -0,0 +1,17 @@ +{ + "folders": [ + { + "path": ".", + "file_exclude_patterns": ["*.sublime-workspace"], + "folder_exclude_patterns": ["dist"] + } + ], + "build_systems": [ + { + "name": "yarn test", + "cmd": ["yarn", "test"], + "file_regex": "\\((...*?):([0-9]*):([0-9]*)\\)", + "working_dir": "$project_path" + } + ] +} diff --git a/img/axis-v3.png b/img/axis-v3.png new file mode 100644 index 00000000000000..94dba4cd133625 Binary files /dev/null and b/img/axis-v3.png differ diff --git a/img/axis-v4.png b/img/axis-v4.png new file mode 100644 index 00000000000000..66fe6594c1a643 Binary files /dev/null and b/img/axis-v4.png differ diff --git a/img/pack-v3.png b/img/pack-v3.png new file mode 100644 index 00000000000000..612c0b44b5a256 Binary files /dev/null and b/img/pack-v3.png differ diff --git a/img/pack-v4.png b/img/pack-v4.png new file mode 100644 index 00000000000000..459f7a9284ba65 Binary files /dev/null and b/img/pack-v4.png differ diff --git a/img/stratify.png b/img/stratify.png new file mode 100644 index 00000000000000..a8a37513381825 Binary files /dev/null and b/img/stratify.png differ diff --git a/index-browserify.js b/index-browserify.js deleted file mode 100644 index c1d22515dceb1b..00000000000000 --- a/index-browserify.js +++ /dev/null @@ -1,3 +0,0 @@ -require("./d3"); -module.exports = d3; -(function () { delete this.d3; })(); // unset global diff --git a/index.js b/index.js index 50835fed3aa4f2..9dcf0bbdd49222 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,31 @@ -var fs = require("fs"), - path = require("path"), - document = require("jsdom").jsdom(""), - window = document.createWindow(); - -// https://github.com/chad3814/CSSStyleDeclaration/issues/3 -var CSSStyleDeclaration_prototype = window.CSSStyleDeclaration.prototype, - CSSStyleDeclaration_setProperty = CSSStyleDeclaration_prototype.setProperty; -CSSStyleDeclaration_prototype.setProperty = function(name, value, priority) { - return CSSStyleDeclaration_setProperty.call(this, name + "", value == null ? null : value + "", priority == null ? null : priority + ""); -}; - -module.exports = (new Function("window", "document", - "return " + fs.readFileSync(path.join(__dirname, "d3.js"), "utf-8")) -)(window, document); +export {version} from "./dist/package.js"; +export * from "d3-array"; +export * from "d3-axis"; +export * from "d3-brush"; +export * from "d3-chord"; +export * from "d3-color"; +export * from "d3-contour"; +export * from "d3-delaunay"; +export * from "d3-dispatch"; +export * from "d3-drag"; +export * from "d3-dsv"; +export * from "d3-ease"; +export * from "d3-fetch"; +export * from "d3-force"; +export * from "d3-format"; +export * from "d3-geo"; +export * from "d3-hierarchy"; +export * from "d3-interpolate"; +export * from "d3-path"; +export * from "d3-polygon"; +export * from "d3-quadtree"; +export * from "d3-random"; +export * from "d3-scale"; +export * from "d3-scale-chromatic"; +export * from "d3-selection"; +export * from "d3-shape"; +export * from "d3-time"; +export * from "d3-time-format"; +export * from "d3-timer"; +export * from "d3-transition"; +export * from "d3-zoom"; diff --git a/lib/colorbrewer/LICENSE b/lib/colorbrewer/LICENSE deleted file mode 100644 index 2ac775d6e36c0e..00000000000000 --- a/lib/colorbrewer/LICENSE +++ /dev/null @@ -1,38 +0,0 @@ -Apache-Style Software License for ColorBrewer software and ColorBrewer Color -Schemes - -Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State -University. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not -use this file except in compliance with the License. You may obtain a copy of -the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -License for the specific language governing permissions and limitations under -the License. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions as source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -2. The end-user documentation included with the redistribution, if any, must -include the following acknowledgment: "This product includes color -specifications and designs developed by Cynthia Brewer -(http://colorbrewer.org/)." Alternately, this acknowledgment may appear in the -software itself, if and wherever such third-party acknowledgments normally -appear. - -4. The name "ColorBrewer" must not be used to endorse or promote products -derived from this software without prior written permission. For written -permission, please contact Cynthia Brewer at cbrewer@psu.edu. - -5. Products derived from this software may not be called "ColorBrewer", nor -may "ColorBrewer" appear in their name, without prior written permission of -Cynthia Brewer. diff --git a/lib/colorbrewer/colorbrewer.css b/lib/colorbrewer/colorbrewer.css deleted file mode 100644 index faed65037a67fd..00000000000000 --- a/lib/colorbrewer/colorbrewer.css +++ /dev/null @@ -1,1690 +0,0 @@ -/* This product includes color specifications and designs developed by Cynthia Brewer (http://colorbrewer.org/). */ -.YlGn .q0-3{fill:rgb(247,252,185)} -.YlGn .q1-3{fill:rgb(173,221,142)} -.YlGn .q2-3{fill:rgb(49,163,84)} -.YlGn .q0-4{fill:rgb(255,255,204)} -.YlGn .q1-4{fill:rgb(194,230,153)} -.YlGn .q2-4{fill:rgb(120,198,121)} -.YlGn .q3-4{fill:rgb(35,132,67)} -.YlGn .q0-5{fill:rgb(255,255,204)} -.YlGn .q1-5{fill:rgb(194,230,153)} -.YlGn .q2-5{fill:rgb(120,198,121)} -.YlGn .q3-5{fill:rgb(49,163,84)} -.YlGn .q4-5{fill:rgb(0,104,55)} -.YlGn .q0-6{fill:rgb(255,255,204)} -.YlGn .q1-6{fill:rgb(217,240,163)} -.YlGn .q2-6{fill:rgb(173,221,142)} -.YlGn .q3-6{fill:rgb(120,198,121)} -.YlGn .q4-6{fill:rgb(49,163,84)} -.YlGn .q5-6{fill:rgb(0,104,55)} -.YlGn .q0-7{fill:rgb(255,255,204)} -.YlGn .q1-7{fill:rgb(217,240,163)} -.YlGn .q2-7{fill:rgb(173,221,142)} -.YlGn .q3-7{fill:rgb(120,198,121)} -.YlGn .q4-7{fill:rgb(65,171,93)} -.YlGn .q5-7{fill:rgb(35,132,67)} -.YlGn .q6-7{fill:rgb(0,90,50)} -.YlGn .q0-8{fill:rgb(255,255,229)} -.YlGn .q1-8{fill:rgb(247,252,185)} -.YlGn .q2-8{fill:rgb(217,240,163)} -.YlGn .q3-8{fill:rgb(173,221,142)} -.YlGn .q4-8{fill:rgb(120,198,121)} -.YlGn .q5-8{fill:rgb(65,171,93)} -.YlGn .q6-8{fill:rgb(35,132,67)} -.YlGn .q7-8{fill:rgb(0,90,50)} -.YlGn .q0-9{fill:rgb(255,255,229)} -.YlGn .q1-9{fill:rgb(247,252,185)} -.YlGn .q2-9{fill:rgb(217,240,163)} -.YlGn .q3-9{fill:rgb(173,221,142)} -.YlGn .q4-9{fill:rgb(120,198,121)} -.YlGn .q5-9{fill:rgb(65,171,93)} -.YlGn .q6-9{fill:rgb(35,132,67)} -.YlGn .q7-9{fill:rgb(0,104,55)} -.YlGn .q8-9{fill:rgb(0,69,41)} -.YlGnBu .q0-3{fill:rgb(237,248,177)} -.YlGnBu .q1-3{fill:rgb(127,205,187)} -.YlGnBu .q2-3{fill:rgb(44,127,184)} -.YlGnBu .q0-4{fill:rgb(255,255,204)} -.YlGnBu .q1-4{fill:rgb(161,218,180)} -.YlGnBu .q2-4{fill:rgb(65,182,196)} -.YlGnBu .q3-4{fill:rgb(34,94,168)} -.YlGnBu .q0-5{fill:rgb(255,255,204)} -.YlGnBu .q1-5{fill:rgb(161,218,180)} -.YlGnBu .q2-5{fill:rgb(65,182,196)} -.YlGnBu .q3-5{fill:rgb(44,127,184)} -.YlGnBu .q4-5{fill:rgb(37,52,148)} -.YlGnBu .q0-6{fill:rgb(255,255,204)} -.YlGnBu .q1-6{fill:rgb(199,233,180)} -.YlGnBu .q2-6{fill:rgb(127,205,187)} -.YlGnBu .q3-6{fill:rgb(65,182,196)} -.YlGnBu .q4-6{fill:rgb(44,127,184)} -.YlGnBu .q5-6{fill:rgb(37,52,148)} -.YlGnBu .q0-7{fill:rgb(255,255,204)} -.YlGnBu .q1-7{fill:rgb(199,233,180)} -.YlGnBu .q2-7{fill:rgb(127,205,187)} -.YlGnBu .q3-7{fill:rgb(65,182,196)} -.YlGnBu .q4-7{fill:rgb(29,145,192)} -.YlGnBu .q5-7{fill:rgb(34,94,168)} -.YlGnBu .q6-7{fill:rgb(12,44,132)} -.YlGnBu .q0-8{fill:rgb(255,255,217)} -.YlGnBu .q1-8{fill:rgb(237,248,177)} -.YlGnBu .q2-8{fill:rgb(199,233,180)} -.YlGnBu .q3-8{fill:rgb(127,205,187)} -.YlGnBu .q4-8{fill:rgb(65,182,196)} -.YlGnBu .q5-8{fill:rgb(29,145,192)} -.YlGnBu .q6-8{fill:rgb(34,94,168)} -.YlGnBu .q7-8{fill:rgb(12,44,132)} -.YlGnBu .q0-9{fill:rgb(255,255,217)} -.YlGnBu .q1-9{fill:rgb(237,248,177)} -.YlGnBu .q2-9{fill:rgb(199,233,180)} -.YlGnBu .q3-9{fill:rgb(127,205,187)} -.YlGnBu .q4-9{fill:rgb(65,182,196)} -.YlGnBu .q5-9{fill:rgb(29,145,192)} -.YlGnBu .q6-9{fill:rgb(34,94,168)} -.YlGnBu .q7-9{fill:rgb(37,52,148)} -.YlGnBu .q8-9{fill:rgb(8,29,88)} -.GnBu .q0-3{fill:rgb(224,243,219)} -.GnBu .q1-3{fill:rgb(168,221,181)} -.GnBu .q2-3{fill:rgb(67,162,202)} -.GnBu .q0-4{fill:rgb(240,249,232)} -.GnBu .q1-4{fill:rgb(186,228,188)} -.GnBu .q2-4{fill:rgb(123,204,196)} -.GnBu .q3-4{fill:rgb(43,140,190)} -.GnBu .q0-5{fill:rgb(240,249,232)} -.GnBu .q1-5{fill:rgb(186,228,188)} -.GnBu .q2-5{fill:rgb(123,204,196)} -.GnBu .q3-5{fill:rgb(67,162,202)} -.GnBu .q4-5{fill:rgb(8,104,172)} -.GnBu .q0-6{fill:rgb(240,249,232)} -.GnBu .q1-6{fill:rgb(204,235,197)} -.GnBu .q2-6{fill:rgb(168,221,181)} -.GnBu .q3-6{fill:rgb(123,204,196)} -.GnBu .q4-6{fill:rgb(67,162,202)} -.GnBu .q5-6{fill:rgb(8,104,172)} -.GnBu .q0-7{fill:rgb(240,249,232)} -.GnBu .q1-7{fill:rgb(204,235,197)} -.GnBu .q2-7{fill:rgb(168,221,181)} -.GnBu .q3-7{fill:rgb(123,204,196)} -.GnBu .q4-7{fill:rgb(78,179,211)} -.GnBu .q5-7{fill:rgb(43,140,190)} -.GnBu .q6-7{fill:rgb(8,88,158)} -.GnBu .q0-8{fill:rgb(247,252,240)} -.GnBu .q1-8{fill:rgb(224,243,219)} -.GnBu .q2-8{fill:rgb(204,235,197)} -.GnBu .q3-8{fill:rgb(168,221,181)} -.GnBu .q4-8{fill:rgb(123,204,196)} -.GnBu .q5-8{fill:rgb(78,179,211)} -.GnBu .q6-8{fill:rgb(43,140,190)} -.GnBu .q7-8{fill:rgb(8,88,158)} -.GnBu .q0-9{fill:rgb(247,252,240)} -.GnBu .q1-9{fill:rgb(224,243,219)} -.GnBu .q2-9{fill:rgb(204,235,197)} -.GnBu .q3-9{fill:rgb(168,221,181)} -.GnBu .q4-9{fill:rgb(123,204,196)} -.GnBu .q5-9{fill:rgb(78,179,211)} -.GnBu .q6-9{fill:rgb(43,140,190)} -.GnBu .q7-9{fill:rgb(8,104,172)} -.GnBu .q8-9{fill:rgb(8,64,129)} -.BuGn .q0-3{fill:rgb(229,245,249)} -.BuGn .q1-3{fill:rgb(153,216,201)} -.BuGn .q2-3{fill:rgb(44,162,95)} -.BuGn .q0-4{fill:rgb(237,248,251)} -.BuGn .q1-4{fill:rgb(178,226,226)} -.BuGn .q2-4{fill:rgb(102,194,164)} -.BuGn .q3-4{fill:rgb(35,139,69)} -.BuGn .q0-5{fill:rgb(237,248,251)} -.BuGn .q1-5{fill:rgb(178,226,226)} -.BuGn .q2-5{fill:rgb(102,194,164)} -.BuGn .q3-5{fill:rgb(44,162,95)} -.BuGn .q4-5{fill:rgb(0,109,44)} -.BuGn .q0-6{fill:rgb(237,248,251)} -.BuGn .q1-6{fill:rgb(204,236,230)} -.BuGn .q2-6{fill:rgb(153,216,201)} -.BuGn .q3-6{fill:rgb(102,194,164)} -.BuGn .q4-6{fill:rgb(44,162,95)} -.BuGn .q5-6{fill:rgb(0,109,44)} -.BuGn .q0-7{fill:rgb(237,248,251)} -.BuGn .q1-7{fill:rgb(204,236,230)} -.BuGn .q2-7{fill:rgb(153,216,201)} -.BuGn .q3-7{fill:rgb(102,194,164)} -.BuGn .q4-7{fill:rgb(65,174,118)} -.BuGn .q5-7{fill:rgb(35,139,69)} -.BuGn .q6-7{fill:rgb(0,88,36)} -.BuGn .q0-8{fill:rgb(247,252,253)} -.BuGn .q1-8{fill:rgb(229,245,249)} -.BuGn .q2-8{fill:rgb(204,236,230)} -.BuGn .q3-8{fill:rgb(153,216,201)} -.BuGn .q4-8{fill:rgb(102,194,164)} -.BuGn .q5-8{fill:rgb(65,174,118)} -.BuGn .q6-8{fill:rgb(35,139,69)} -.BuGn .q7-8{fill:rgb(0,88,36)} -.BuGn .q0-9{fill:rgb(247,252,253)} -.BuGn .q1-9{fill:rgb(229,245,249)} -.BuGn .q2-9{fill:rgb(204,236,230)} -.BuGn .q3-9{fill:rgb(153,216,201)} -.BuGn .q4-9{fill:rgb(102,194,164)} -.BuGn .q5-9{fill:rgb(65,174,118)} -.BuGn .q6-9{fill:rgb(35,139,69)} -.BuGn .q7-9{fill:rgb(0,109,44)} -.BuGn .q8-9{fill:rgb(0,68,27)} -.PuBuGn .q0-3{fill:rgb(236,226,240)} -.PuBuGn .q1-3{fill:rgb(166,189,219)} -.PuBuGn .q2-3{fill:rgb(28,144,153)} -.PuBuGn .q0-4{fill:rgb(246,239,247)} -.PuBuGn .q1-4{fill:rgb(189,201,225)} -.PuBuGn .q2-4{fill:rgb(103,169,207)} -.PuBuGn .q3-4{fill:rgb(2,129,138)} -.PuBuGn .q0-5{fill:rgb(246,239,247)} -.PuBuGn .q1-5{fill:rgb(189,201,225)} -.PuBuGn .q2-5{fill:rgb(103,169,207)} -.PuBuGn .q3-5{fill:rgb(28,144,153)} -.PuBuGn .q4-5{fill:rgb(1,108,89)} -.PuBuGn .q0-6{fill:rgb(246,239,247)} -.PuBuGn .q1-6{fill:rgb(208,209,230)} -.PuBuGn .q2-6{fill:rgb(166,189,219)} -.PuBuGn .q3-6{fill:rgb(103,169,207)} -.PuBuGn .q4-6{fill:rgb(28,144,153)} -.PuBuGn .q5-6{fill:rgb(1,108,89)} -.PuBuGn .q0-7{fill:rgb(246,239,247)} -.PuBuGn .q1-7{fill:rgb(208,209,230)} -.PuBuGn .q2-7{fill:rgb(166,189,219)} -.PuBuGn .q3-7{fill:rgb(103,169,207)} -.PuBuGn .q4-7{fill:rgb(54,144,192)} -.PuBuGn .q5-7{fill:rgb(2,129,138)} -.PuBuGn .q6-7{fill:rgb(1,100,80)} -.PuBuGn .q0-8{fill:rgb(255,247,251)} -.PuBuGn .q1-8{fill:rgb(236,226,240)} -.PuBuGn .q2-8{fill:rgb(208,209,230)} -.PuBuGn .q3-8{fill:rgb(166,189,219)} -.PuBuGn .q4-8{fill:rgb(103,169,207)} -.PuBuGn .q5-8{fill:rgb(54,144,192)} -.PuBuGn .q6-8{fill:rgb(2,129,138)} -.PuBuGn .q7-8{fill:rgb(1,100,80)} -.PuBuGn .q0-9{fill:rgb(255,247,251)} -.PuBuGn .q1-9{fill:rgb(236,226,240)} -.PuBuGn .q2-9{fill:rgb(208,209,230)} -.PuBuGn .q3-9{fill:rgb(166,189,219)} -.PuBuGn .q4-9{fill:rgb(103,169,207)} -.PuBuGn .q5-9{fill:rgb(54,144,192)} -.PuBuGn .q6-9{fill:rgb(2,129,138)} -.PuBuGn .q7-9{fill:rgb(1,108,89)} -.PuBuGn .q8-9{fill:rgb(1,70,54)} -.PuBu .q0-3{fill:rgb(236,231,242)} -.PuBu .q1-3{fill:rgb(166,189,219)} -.PuBu .q2-3{fill:rgb(43,140,190)} -.PuBu .q0-4{fill:rgb(241,238,246)} -.PuBu .q1-4{fill:rgb(189,201,225)} -.PuBu .q2-4{fill:rgb(116,169,207)} -.PuBu .q3-4{fill:rgb(5,112,176)} -.PuBu .q0-5{fill:rgb(241,238,246)} -.PuBu .q1-5{fill:rgb(189,201,225)} -.PuBu .q2-5{fill:rgb(116,169,207)} -.PuBu .q3-5{fill:rgb(43,140,190)} -.PuBu .q4-5{fill:rgb(4,90,141)} -.PuBu .q0-6{fill:rgb(241,238,246)} -.PuBu .q1-6{fill:rgb(208,209,230)} -.PuBu .q2-6{fill:rgb(166,189,219)} -.PuBu .q3-6{fill:rgb(116,169,207)} -.PuBu .q4-6{fill:rgb(43,140,190)} -.PuBu .q5-6{fill:rgb(4,90,141)} -.PuBu .q0-7{fill:rgb(241,238,246)} -.PuBu .q1-7{fill:rgb(208,209,230)} -.PuBu .q2-7{fill:rgb(166,189,219)} -.PuBu .q3-7{fill:rgb(116,169,207)} -.PuBu .q4-7{fill:rgb(54,144,192)} -.PuBu .q5-7{fill:rgb(5,112,176)} -.PuBu .q6-7{fill:rgb(3,78,123)} -.PuBu .q0-8{fill:rgb(255,247,251)} -.PuBu .q1-8{fill:rgb(236,231,242)} -.PuBu .q2-8{fill:rgb(208,209,230)} -.PuBu .q3-8{fill:rgb(166,189,219)} -.PuBu .q4-8{fill:rgb(116,169,207)} -.PuBu .q5-8{fill:rgb(54,144,192)} -.PuBu .q6-8{fill:rgb(5,112,176)} -.PuBu .q7-8{fill:rgb(3,78,123)} -.PuBu .q0-9{fill:rgb(255,247,251)} -.PuBu .q1-9{fill:rgb(236,231,242)} -.PuBu .q2-9{fill:rgb(208,209,230)} -.PuBu .q3-9{fill:rgb(166,189,219)} -.PuBu .q4-9{fill:rgb(116,169,207)} -.PuBu .q5-9{fill:rgb(54,144,192)} -.PuBu .q6-9{fill:rgb(5,112,176)} -.PuBu .q7-9{fill:rgb(4,90,141)} -.PuBu .q8-9{fill:rgb(2,56,88)} -.BuPu .q0-3{fill:rgb(224,236,244)} -.BuPu .q1-3{fill:rgb(158,188,218)} -.BuPu .q2-3{fill:rgb(136,86,167)} -.BuPu .q0-4{fill:rgb(237,248,251)} -.BuPu .q1-4{fill:rgb(179,205,227)} -.BuPu .q2-4{fill:rgb(140,150,198)} -.BuPu .q3-4{fill:rgb(136,65,157)} -.BuPu .q0-5{fill:rgb(237,248,251)} -.BuPu .q1-5{fill:rgb(179,205,227)} -.BuPu .q2-5{fill:rgb(140,150,198)} -.BuPu .q3-5{fill:rgb(136,86,167)} -.BuPu .q4-5{fill:rgb(129,15,124)} -.BuPu .q0-6{fill:rgb(237,248,251)} -.BuPu .q1-6{fill:rgb(191,211,230)} -.BuPu .q2-6{fill:rgb(158,188,218)} -.BuPu .q3-6{fill:rgb(140,150,198)} -.BuPu .q4-6{fill:rgb(136,86,167)} -.BuPu .q5-6{fill:rgb(129,15,124)} -.BuPu .q0-7{fill:rgb(237,248,251)} -.BuPu .q1-7{fill:rgb(191,211,230)} -.BuPu .q2-7{fill:rgb(158,188,218)} -.BuPu .q3-7{fill:rgb(140,150,198)} -.BuPu .q4-7{fill:rgb(140,107,177)} -.BuPu .q5-7{fill:rgb(136,65,157)} -.BuPu .q6-7{fill:rgb(110,1,107)} -.BuPu .q0-8{fill:rgb(247,252,253)} -.BuPu .q1-8{fill:rgb(224,236,244)} -.BuPu .q2-8{fill:rgb(191,211,230)} -.BuPu .q3-8{fill:rgb(158,188,218)} -.BuPu .q4-8{fill:rgb(140,150,198)} -.BuPu .q5-8{fill:rgb(140,107,177)} -.BuPu .q6-8{fill:rgb(136,65,157)} -.BuPu .q7-8{fill:rgb(110,1,107)} -.BuPu .q0-9{fill:rgb(247,252,253)} -.BuPu .q1-9{fill:rgb(224,236,244)} -.BuPu .q2-9{fill:rgb(191,211,230)} -.BuPu .q3-9{fill:rgb(158,188,218)} -.BuPu .q4-9{fill:rgb(140,150,198)} -.BuPu .q5-9{fill:rgb(140,107,177)} -.BuPu .q6-9{fill:rgb(136,65,157)} -.BuPu .q7-9{fill:rgb(129,15,124)} -.BuPu .q8-9{fill:rgb(77,0,75)} -.RdPu .q0-3{fill:rgb(253,224,221)} -.RdPu .q1-3{fill:rgb(250,159,181)} -.RdPu .q2-3{fill:rgb(197,27,138)} -.RdPu .q0-4{fill:rgb(254,235,226)} -.RdPu .q1-4{fill:rgb(251,180,185)} -.RdPu .q2-4{fill:rgb(247,104,161)} -.RdPu .q3-4{fill:rgb(174,1,126)} -.RdPu .q0-5{fill:rgb(254,235,226)} -.RdPu .q1-5{fill:rgb(251,180,185)} -.RdPu .q2-5{fill:rgb(247,104,161)} -.RdPu .q3-5{fill:rgb(197,27,138)} -.RdPu .q4-5{fill:rgb(122,1,119)} -.RdPu .q0-6{fill:rgb(254,235,226)} -.RdPu .q1-6{fill:rgb(252,197,192)} -.RdPu .q2-6{fill:rgb(250,159,181)} -.RdPu .q3-6{fill:rgb(247,104,161)} -.RdPu .q4-6{fill:rgb(197,27,138)} -.RdPu .q5-6{fill:rgb(122,1,119)} -.RdPu .q0-7{fill:rgb(254,235,226)} -.RdPu .q1-7{fill:rgb(252,197,192)} -.RdPu .q2-7{fill:rgb(250,159,181)} -.RdPu .q3-7{fill:rgb(247,104,161)} -.RdPu .q4-7{fill:rgb(221,52,151)} -.RdPu .q5-7{fill:rgb(174,1,126)} -.RdPu .q6-7{fill:rgb(122,1,119)} -.RdPu .q0-8{fill:rgb(255,247,243)} -.RdPu .q1-8{fill:rgb(253,224,221)} -.RdPu .q2-8{fill:rgb(252,197,192)} -.RdPu .q3-8{fill:rgb(250,159,181)} -.RdPu .q4-8{fill:rgb(247,104,161)} -.RdPu .q5-8{fill:rgb(221,52,151)} -.RdPu .q6-8{fill:rgb(174,1,126)} -.RdPu .q7-8{fill:rgb(122,1,119)} -.RdPu .q0-9{fill:rgb(255,247,243)} -.RdPu .q1-9{fill:rgb(253,224,221)} -.RdPu .q2-9{fill:rgb(252,197,192)} -.RdPu .q3-9{fill:rgb(250,159,181)} -.RdPu .q4-9{fill:rgb(247,104,161)} -.RdPu .q5-9{fill:rgb(221,52,151)} -.RdPu .q6-9{fill:rgb(174,1,126)} -.RdPu .q7-9{fill:rgb(122,1,119)} -.RdPu .q8-9{fill:rgb(73,0,106)} -.PuRd .q0-3{fill:rgb(231,225,239)} -.PuRd .q1-3{fill:rgb(201,148,199)} -.PuRd .q2-3{fill:rgb(221,28,119)} -.PuRd .q0-4{fill:rgb(241,238,246)} -.PuRd .q1-4{fill:rgb(215,181,216)} -.PuRd .q2-4{fill:rgb(223,101,176)} -.PuRd .q3-4{fill:rgb(206,18,86)} -.PuRd .q0-5{fill:rgb(241,238,246)} -.PuRd .q1-5{fill:rgb(215,181,216)} -.PuRd .q2-5{fill:rgb(223,101,176)} -.PuRd .q3-5{fill:rgb(221,28,119)} -.PuRd .q4-5{fill:rgb(152,0,67)} -.PuRd .q0-6{fill:rgb(241,238,246)} -.PuRd .q1-6{fill:rgb(212,185,218)} -.PuRd .q2-6{fill:rgb(201,148,199)} -.PuRd .q3-6{fill:rgb(223,101,176)} -.PuRd .q4-6{fill:rgb(221,28,119)} -.PuRd .q5-6{fill:rgb(152,0,67)} -.PuRd .q0-7{fill:rgb(241,238,246)} -.PuRd .q1-7{fill:rgb(212,185,218)} -.PuRd .q2-7{fill:rgb(201,148,199)} -.PuRd .q3-7{fill:rgb(223,101,176)} -.PuRd .q4-7{fill:rgb(231,41,138)} -.PuRd .q5-7{fill:rgb(206,18,86)} -.PuRd .q6-7{fill:rgb(145,0,63)} -.PuRd .q0-8{fill:rgb(247,244,249)} -.PuRd .q1-8{fill:rgb(231,225,239)} -.PuRd .q2-8{fill:rgb(212,185,218)} -.PuRd .q3-8{fill:rgb(201,148,199)} -.PuRd .q4-8{fill:rgb(223,101,176)} -.PuRd .q5-8{fill:rgb(231,41,138)} -.PuRd .q6-8{fill:rgb(206,18,86)} -.PuRd .q7-8{fill:rgb(145,0,63)} -.PuRd .q0-9{fill:rgb(247,244,249)} -.PuRd .q1-9{fill:rgb(231,225,239)} -.PuRd .q2-9{fill:rgb(212,185,218)} -.PuRd .q3-9{fill:rgb(201,148,199)} -.PuRd .q4-9{fill:rgb(223,101,176)} -.PuRd .q5-9{fill:rgb(231,41,138)} -.PuRd .q6-9{fill:rgb(206,18,86)} -.PuRd .q7-9{fill:rgb(152,0,67)} -.PuRd .q8-9{fill:rgb(103,0,31)} -.OrRd .q0-3{fill:rgb(254,232,200)} -.OrRd .q1-3{fill:rgb(253,187,132)} -.OrRd .q2-3{fill:rgb(227,74,51)} -.OrRd .q0-4{fill:rgb(254,240,217)} -.OrRd .q1-4{fill:rgb(253,204,138)} -.OrRd .q2-4{fill:rgb(252,141,89)} -.OrRd .q3-4{fill:rgb(215,48,31)} -.OrRd .q0-5{fill:rgb(254,240,217)} -.OrRd .q1-5{fill:rgb(253,204,138)} -.OrRd .q2-5{fill:rgb(252,141,89)} -.OrRd .q3-5{fill:rgb(227,74,51)} -.OrRd .q4-5{fill:rgb(179,0,0)} -.OrRd .q0-6{fill:rgb(254,240,217)} -.OrRd .q1-6{fill:rgb(253,212,158)} -.OrRd .q2-6{fill:rgb(253,187,132)} -.OrRd .q3-6{fill:rgb(252,141,89)} -.OrRd .q4-6{fill:rgb(227,74,51)} -.OrRd .q5-6{fill:rgb(179,0,0)} -.OrRd .q0-7{fill:rgb(254,240,217)} -.OrRd .q1-7{fill:rgb(253,212,158)} -.OrRd .q2-7{fill:rgb(253,187,132)} -.OrRd .q3-7{fill:rgb(252,141,89)} -.OrRd .q4-7{fill:rgb(239,101,72)} -.OrRd .q5-7{fill:rgb(215,48,31)} -.OrRd .q6-7{fill:rgb(153,0,0)} -.OrRd .q0-8{fill:rgb(255,247,236)} -.OrRd .q1-8{fill:rgb(254,232,200)} -.OrRd .q2-8{fill:rgb(253,212,158)} -.OrRd .q3-8{fill:rgb(253,187,132)} -.OrRd .q4-8{fill:rgb(252,141,89)} -.OrRd .q5-8{fill:rgb(239,101,72)} -.OrRd .q6-8{fill:rgb(215,48,31)} -.OrRd .q7-8{fill:rgb(153,0,0)} -.OrRd .q0-9{fill:rgb(255,247,236)} -.OrRd .q1-9{fill:rgb(254,232,200)} -.OrRd .q2-9{fill:rgb(253,212,158)} -.OrRd .q3-9{fill:rgb(253,187,132)} -.OrRd .q4-9{fill:rgb(252,141,89)} -.OrRd .q5-9{fill:rgb(239,101,72)} -.OrRd .q6-9{fill:rgb(215,48,31)} -.OrRd .q7-9{fill:rgb(179,0,0)} -.OrRd .q8-9{fill:rgb(127,0,0)} -.YlOrRd .q0-3{fill:rgb(255,237,160)} -.YlOrRd .q1-3{fill:rgb(254,178,76)} -.YlOrRd .q2-3{fill:rgb(240,59,32)} -.YlOrRd .q0-4{fill:rgb(255,255,178)} -.YlOrRd .q1-4{fill:rgb(254,204,92)} -.YlOrRd .q2-4{fill:rgb(253,141,60)} -.YlOrRd .q3-4{fill:rgb(227,26,28)} -.YlOrRd .q0-5{fill:rgb(255,255,178)} -.YlOrRd .q1-5{fill:rgb(254,204,92)} -.YlOrRd .q2-5{fill:rgb(253,141,60)} -.YlOrRd .q3-5{fill:rgb(240,59,32)} -.YlOrRd .q4-5{fill:rgb(189,0,38)} -.YlOrRd .q0-6{fill:rgb(255,255,178)} -.YlOrRd .q1-6{fill:rgb(254,217,118)} -.YlOrRd .q2-6{fill:rgb(254,178,76)} -.YlOrRd .q3-6{fill:rgb(253,141,60)} -.YlOrRd .q4-6{fill:rgb(240,59,32)} -.YlOrRd .q5-6{fill:rgb(189,0,38)} -.YlOrRd .q0-7{fill:rgb(255,255,178)} -.YlOrRd .q1-7{fill:rgb(254,217,118)} -.YlOrRd .q2-7{fill:rgb(254,178,76)} -.YlOrRd .q3-7{fill:rgb(253,141,60)} -.YlOrRd .q4-7{fill:rgb(252,78,42)} -.YlOrRd .q5-7{fill:rgb(227,26,28)} -.YlOrRd .q6-7{fill:rgb(177,0,38)} -.YlOrRd .q0-8{fill:rgb(255,255,204)} -.YlOrRd .q1-8{fill:rgb(255,237,160)} -.YlOrRd .q2-8{fill:rgb(254,217,118)} -.YlOrRd .q3-8{fill:rgb(254,178,76)} -.YlOrRd .q4-8{fill:rgb(253,141,60)} -.YlOrRd .q5-8{fill:rgb(252,78,42)} -.YlOrRd .q6-8{fill:rgb(227,26,28)} -.YlOrRd .q7-8{fill:rgb(177,0,38)} -.YlOrRd .q0-9{fill:rgb(255,255,204)} -.YlOrRd .q1-9{fill:rgb(255,237,160)} -.YlOrRd .q2-9{fill:rgb(254,217,118)} -.YlOrRd .q3-9{fill:rgb(254,178,76)} -.YlOrRd .q4-9{fill:rgb(253,141,60)} -.YlOrRd .q5-9{fill:rgb(252,78,42)} -.YlOrRd .q6-9{fill:rgb(227,26,28)} -.YlOrRd .q7-9{fill:rgb(189,0,38)} -.YlOrRd .q8-9{fill:rgb(128,0,38)} -.YlOrBr .q0-3{fill:rgb(255,247,188)} -.YlOrBr .q1-3{fill:rgb(254,196,79)} -.YlOrBr .q2-3{fill:rgb(217,95,14)} -.YlOrBr .q0-4{fill:rgb(255,255,212)} -.YlOrBr .q1-4{fill:rgb(254,217,142)} -.YlOrBr .q2-4{fill:rgb(254,153,41)} -.YlOrBr .q3-4{fill:rgb(204,76,2)} -.YlOrBr .q0-5{fill:rgb(255,255,212)} -.YlOrBr .q1-5{fill:rgb(254,217,142)} -.YlOrBr .q2-5{fill:rgb(254,153,41)} -.YlOrBr .q3-5{fill:rgb(217,95,14)} -.YlOrBr .q4-5{fill:rgb(153,52,4)} -.YlOrBr .q0-6{fill:rgb(255,255,212)} -.YlOrBr .q1-6{fill:rgb(254,227,145)} -.YlOrBr .q2-6{fill:rgb(254,196,79)} -.YlOrBr .q3-6{fill:rgb(254,153,41)} -.YlOrBr .q4-6{fill:rgb(217,95,14)} -.YlOrBr .q5-6{fill:rgb(153,52,4)} -.YlOrBr .q0-7{fill:rgb(255,255,212)} -.YlOrBr .q1-7{fill:rgb(254,227,145)} -.YlOrBr .q2-7{fill:rgb(254,196,79)} -.YlOrBr .q3-7{fill:rgb(254,153,41)} -.YlOrBr .q4-7{fill:rgb(236,112,20)} -.YlOrBr .q5-7{fill:rgb(204,76,2)} -.YlOrBr .q6-7{fill:rgb(140,45,4)} -.YlOrBr .q0-8{fill:rgb(255,255,229)} -.YlOrBr .q1-8{fill:rgb(255,247,188)} -.YlOrBr .q2-8{fill:rgb(254,227,145)} -.YlOrBr .q3-8{fill:rgb(254,196,79)} -.YlOrBr .q4-8{fill:rgb(254,153,41)} -.YlOrBr .q5-8{fill:rgb(236,112,20)} -.YlOrBr .q6-8{fill:rgb(204,76,2)} -.YlOrBr .q7-8{fill:rgb(140,45,4)} -.YlOrBr .q0-9{fill:rgb(255,255,229)} -.YlOrBr .q1-9{fill:rgb(255,247,188)} -.YlOrBr .q2-9{fill:rgb(254,227,145)} -.YlOrBr .q3-9{fill:rgb(254,196,79)} -.YlOrBr .q4-9{fill:rgb(254,153,41)} -.YlOrBr .q5-9{fill:rgb(236,112,20)} -.YlOrBr .q6-9{fill:rgb(204,76,2)} -.YlOrBr .q7-9{fill:rgb(153,52,4)} -.YlOrBr .q8-9{fill:rgb(102,37,6)} -.Purples .q0-3{fill:rgb(239,237,245)} -.Purples .q1-3{fill:rgb(188,189,220)} -.Purples .q2-3{fill:rgb(117,107,177)} -.Purples .q0-4{fill:rgb(242,240,247)} -.Purples .q1-4{fill:rgb(203,201,226)} -.Purples .q2-4{fill:rgb(158,154,200)} -.Purples .q3-4{fill:rgb(106,81,163)} -.Purples .q0-5{fill:rgb(242,240,247)} -.Purples .q1-5{fill:rgb(203,201,226)} -.Purples .q2-5{fill:rgb(158,154,200)} -.Purples .q3-5{fill:rgb(117,107,177)} -.Purples .q4-5{fill:rgb(84,39,143)} -.Purples .q0-6{fill:rgb(242,240,247)} -.Purples .q1-6{fill:rgb(218,218,235)} -.Purples .q2-6{fill:rgb(188,189,220)} -.Purples .q3-6{fill:rgb(158,154,200)} -.Purples .q4-6{fill:rgb(117,107,177)} -.Purples .q5-6{fill:rgb(84,39,143)} -.Purples .q0-7{fill:rgb(242,240,247)} -.Purples .q1-7{fill:rgb(218,218,235)} -.Purples .q2-7{fill:rgb(188,189,220)} -.Purples .q3-7{fill:rgb(158,154,200)} -.Purples .q4-7{fill:rgb(128,125,186)} -.Purples .q5-7{fill:rgb(106,81,163)} -.Purples .q6-7{fill:rgb(74,20,134)} -.Purples .q0-8{fill:rgb(252,251,253)} -.Purples .q1-8{fill:rgb(239,237,245)} -.Purples .q2-8{fill:rgb(218,218,235)} -.Purples .q3-8{fill:rgb(188,189,220)} -.Purples .q4-8{fill:rgb(158,154,200)} -.Purples .q5-8{fill:rgb(128,125,186)} -.Purples .q6-8{fill:rgb(106,81,163)} -.Purples .q7-8{fill:rgb(74,20,134)} -.Purples .q0-9{fill:rgb(252,251,253)} -.Purples .q1-9{fill:rgb(239,237,245)} -.Purples .q2-9{fill:rgb(218,218,235)} -.Purples .q3-9{fill:rgb(188,189,220)} -.Purples .q4-9{fill:rgb(158,154,200)} -.Purples .q5-9{fill:rgb(128,125,186)} -.Purples .q6-9{fill:rgb(106,81,163)} -.Purples .q7-9{fill:rgb(84,39,143)} -.Purples .q8-9{fill:rgb(63,0,125)} -.Blues .q0-3{fill:rgb(222,235,247)} -.Blues .q1-3{fill:rgb(158,202,225)} -.Blues .q2-3{fill:rgb(49,130,189)} -.Blues .q0-4{fill:rgb(239,243,255)} -.Blues .q1-4{fill:rgb(189,215,231)} -.Blues .q2-4{fill:rgb(107,174,214)} -.Blues .q3-4{fill:rgb(33,113,181)} -.Blues .q0-5{fill:rgb(239,243,255)} -.Blues .q1-5{fill:rgb(189,215,231)} -.Blues .q2-5{fill:rgb(107,174,214)} -.Blues .q3-5{fill:rgb(49,130,189)} -.Blues .q4-5{fill:rgb(8,81,156)} -.Blues .q0-6{fill:rgb(239,243,255)} -.Blues .q1-6{fill:rgb(198,219,239)} -.Blues .q2-6{fill:rgb(158,202,225)} -.Blues .q3-6{fill:rgb(107,174,214)} -.Blues .q4-6{fill:rgb(49,130,189)} -.Blues .q5-6{fill:rgb(8,81,156)} -.Blues .q0-7{fill:rgb(239,243,255)} -.Blues .q1-7{fill:rgb(198,219,239)} -.Blues .q2-7{fill:rgb(158,202,225)} -.Blues .q3-7{fill:rgb(107,174,214)} -.Blues .q4-7{fill:rgb(66,146,198)} -.Blues .q5-7{fill:rgb(33,113,181)} -.Blues .q6-7{fill:rgb(8,69,148)} -.Blues .q0-8{fill:rgb(247,251,255)} -.Blues .q1-8{fill:rgb(222,235,247)} -.Blues .q2-8{fill:rgb(198,219,239)} -.Blues .q3-8{fill:rgb(158,202,225)} -.Blues .q4-8{fill:rgb(107,174,214)} -.Blues .q5-8{fill:rgb(66,146,198)} -.Blues .q6-8{fill:rgb(33,113,181)} -.Blues .q7-8{fill:rgb(8,69,148)} -.Blues .q0-9{fill:rgb(247,251,255)} -.Blues .q1-9{fill:rgb(222,235,247)} -.Blues .q2-9{fill:rgb(198,219,239)} -.Blues .q3-9{fill:rgb(158,202,225)} -.Blues .q4-9{fill:rgb(107,174,214)} -.Blues .q5-9{fill:rgb(66,146,198)} -.Blues .q6-9{fill:rgb(33,113,181)} -.Blues .q7-9{fill:rgb(8,81,156)} -.Blues .q8-9{fill:rgb(8,48,107)} -.Greens .q0-3{fill:rgb(229,245,224)} -.Greens .q1-3{fill:rgb(161,217,155)} -.Greens .q2-3{fill:rgb(49,163,84)} -.Greens .q0-4{fill:rgb(237,248,233)} -.Greens .q1-4{fill:rgb(186,228,179)} -.Greens .q2-4{fill:rgb(116,196,118)} -.Greens .q3-4{fill:rgb(35,139,69)} -.Greens .q0-5{fill:rgb(237,248,233)} -.Greens .q1-5{fill:rgb(186,228,179)} -.Greens .q2-5{fill:rgb(116,196,118)} -.Greens .q3-5{fill:rgb(49,163,84)} -.Greens .q4-5{fill:rgb(0,109,44)} -.Greens .q0-6{fill:rgb(237,248,233)} -.Greens .q1-6{fill:rgb(199,233,192)} -.Greens .q2-6{fill:rgb(161,217,155)} -.Greens .q3-6{fill:rgb(116,196,118)} -.Greens .q4-6{fill:rgb(49,163,84)} -.Greens .q5-6{fill:rgb(0,109,44)} -.Greens .q0-7{fill:rgb(237,248,233)} -.Greens .q1-7{fill:rgb(199,233,192)} -.Greens .q2-7{fill:rgb(161,217,155)} -.Greens .q3-7{fill:rgb(116,196,118)} -.Greens .q4-7{fill:rgb(65,171,93)} -.Greens .q5-7{fill:rgb(35,139,69)} -.Greens .q6-7{fill:rgb(0,90,50)} -.Greens .q0-8{fill:rgb(247,252,245)} -.Greens .q1-8{fill:rgb(229,245,224)} -.Greens .q2-8{fill:rgb(199,233,192)} -.Greens .q3-8{fill:rgb(161,217,155)} -.Greens .q4-8{fill:rgb(116,196,118)} -.Greens .q5-8{fill:rgb(65,171,93)} -.Greens .q6-8{fill:rgb(35,139,69)} -.Greens .q7-8{fill:rgb(0,90,50)} -.Greens .q0-9{fill:rgb(247,252,245)} -.Greens .q1-9{fill:rgb(229,245,224)} -.Greens .q2-9{fill:rgb(199,233,192)} -.Greens .q3-9{fill:rgb(161,217,155)} -.Greens .q4-9{fill:rgb(116,196,118)} -.Greens .q5-9{fill:rgb(65,171,93)} -.Greens .q6-9{fill:rgb(35,139,69)} -.Greens .q7-9{fill:rgb(0,109,44)} -.Greens .q8-9{fill:rgb(0,68,27)} -.Oranges .q0-3{fill:rgb(254,230,206)} -.Oranges .q1-3{fill:rgb(253,174,107)} -.Oranges .q2-3{fill:rgb(230,85,13)} -.Oranges .q0-4{fill:rgb(254,237,222)} -.Oranges .q1-4{fill:rgb(253,190,133)} -.Oranges .q2-4{fill:rgb(253,141,60)} -.Oranges .q3-4{fill:rgb(217,71,1)} -.Oranges .q0-5{fill:rgb(254,237,222)} -.Oranges .q1-5{fill:rgb(253,190,133)} -.Oranges .q2-5{fill:rgb(253,141,60)} -.Oranges .q3-5{fill:rgb(230,85,13)} -.Oranges .q4-5{fill:rgb(166,54,3)} -.Oranges .q0-6{fill:rgb(254,237,222)} -.Oranges .q1-6{fill:rgb(253,208,162)} -.Oranges .q2-6{fill:rgb(253,174,107)} -.Oranges .q3-6{fill:rgb(253,141,60)} -.Oranges .q4-6{fill:rgb(230,85,13)} -.Oranges .q5-6{fill:rgb(166,54,3)} -.Oranges .q0-7{fill:rgb(254,237,222)} -.Oranges .q1-7{fill:rgb(253,208,162)} -.Oranges .q2-7{fill:rgb(253,174,107)} -.Oranges .q3-7{fill:rgb(253,141,60)} -.Oranges .q4-7{fill:rgb(241,105,19)} -.Oranges .q5-7{fill:rgb(217,72,1)} -.Oranges .q6-7{fill:rgb(140,45,4)} -.Oranges .q0-8{fill:rgb(255,245,235)} -.Oranges .q1-8{fill:rgb(254,230,206)} -.Oranges .q2-8{fill:rgb(253,208,162)} -.Oranges .q3-8{fill:rgb(253,174,107)} -.Oranges .q4-8{fill:rgb(253,141,60)} -.Oranges .q5-8{fill:rgb(241,105,19)} -.Oranges .q6-8{fill:rgb(217,72,1)} -.Oranges .q7-8{fill:rgb(140,45,4)} -.Oranges .q0-9{fill:rgb(255,245,235)} -.Oranges .q1-9{fill:rgb(254,230,206)} -.Oranges .q2-9{fill:rgb(253,208,162)} -.Oranges .q3-9{fill:rgb(253,174,107)} -.Oranges .q4-9{fill:rgb(253,141,60)} -.Oranges .q5-9{fill:rgb(241,105,19)} -.Oranges .q6-9{fill:rgb(217,72,1)} -.Oranges .q7-9{fill:rgb(166,54,3)} -.Oranges .q8-9{fill:rgb(127,39,4)} -.Reds .q0-3{fill:rgb(254,224,210)} -.Reds .q1-3{fill:rgb(252,146,114)} -.Reds .q2-3{fill:rgb(222,45,38)} -.Reds .q0-4{fill:rgb(254,229,217)} -.Reds .q1-4{fill:rgb(252,174,145)} -.Reds .q2-4{fill:rgb(251,106,74)} -.Reds .q3-4{fill:rgb(203,24,29)} -.Reds .q0-5{fill:rgb(254,229,217)} -.Reds .q1-5{fill:rgb(252,174,145)} -.Reds .q2-5{fill:rgb(251,106,74)} -.Reds .q3-5{fill:rgb(222,45,38)} -.Reds .q4-5{fill:rgb(165,15,21)} -.Reds .q0-6{fill:rgb(254,229,217)} -.Reds .q1-6{fill:rgb(252,187,161)} -.Reds .q2-6{fill:rgb(252,146,114)} -.Reds .q3-6{fill:rgb(251,106,74)} -.Reds .q4-6{fill:rgb(222,45,38)} -.Reds .q5-6{fill:rgb(165,15,21)} -.Reds .q0-7{fill:rgb(254,229,217)} -.Reds .q1-7{fill:rgb(252,187,161)} -.Reds .q2-7{fill:rgb(252,146,114)} -.Reds .q3-7{fill:rgb(251,106,74)} -.Reds .q4-7{fill:rgb(239,59,44)} -.Reds .q5-7{fill:rgb(203,24,29)} -.Reds .q6-7{fill:rgb(153,0,13)} -.Reds .q0-8{fill:rgb(255,245,240)} -.Reds .q1-8{fill:rgb(254,224,210)} -.Reds .q2-8{fill:rgb(252,187,161)} -.Reds .q3-8{fill:rgb(252,146,114)} -.Reds .q4-8{fill:rgb(251,106,74)} -.Reds .q5-8{fill:rgb(239,59,44)} -.Reds .q6-8{fill:rgb(203,24,29)} -.Reds .q7-8{fill:rgb(153,0,13)} -.Reds .q0-9{fill:rgb(255,245,240)} -.Reds .q1-9{fill:rgb(254,224,210)} -.Reds .q2-9{fill:rgb(252,187,161)} -.Reds .q3-9{fill:rgb(252,146,114)} -.Reds .q4-9{fill:rgb(251,106,74)} -.Reds .q5-9{fill:rgb(239,59,44)} -.Reds .q6-9{fill:rgb(203,24,29)} -.Reds .q7-9{fill:rgb(165,15,21)} -.Reds .q8-9{fill:rgb(103,0,13)} -.Greys .q0-3{fill:rgb(240,240,240)} -.Greys .q1-3{fill:rgb(189,189,189)} -.Greys .q2-3{fill:rgb(99,99,99)} -.Greys .q0-4{fill:rgb(247,247,247)} -.Greys .q1-4{fill:rgb(204,204,204)} -.Greys .q2-4{fill:rgb(150,150,150)} -.Greys .q3-4{fill:rgb(82,82,82)} -.Greys .q0-5{fill:rgb(247,247,247)} -.Greys .q1-5{fill:rgb(204,204,204)} -.Greys .q2-5{fill:rgb(150,150,150)} -.Greys .q3-5{fill:rgb(99,99,99)} -.Greys .q4-5{fill:rgb(37,37,37)} -.Greys .q0-6{fill:rgb(247,247,247)} -.Greys .q1-6{fill:rgb(217,217,217)} -.Greys .q2-6{fill:rgb(189,189,189)} -.Greys .q3-6{fill:rgb(150,150,150)} -.Greys .q4-6{fill:rgb(99,99,99)} -.Greys .q5-6{fill:rgb(37,37,37)} -.Greys .q0-7{fill:rgb(247,247,247)} -.Greys .q1-7{fill:rgb(217,217,217)} -.Greys .q2-7{fill:rgb(189,189,189)} -.Greys .q3-7{fill:rgb(150,150,150)} -.Greys .q4-7{fill:rgb(115,115,115)} -.Greys .q5-7{fill:rgb(82,82,82)} -.Greys .q6-7{fill:rgb(37,37,37)} -.Greys .q0-8{fill:rgb(255,255,255)} -.Greys .q1-8{fill:rgb(240,240,240)} -.Greys .q2-8{fill:rgb(217,217,217)} -.Greys .q3-8{fill:rgb(189,189,189)} -.Greys .q4-8{fill:rgb(150,150,150)} -.Greys .q5-8{fill:rgb(115,115,115)} -.Greys .q6-8{fill:rgb(82,82,82)} -.Greys .q7-8{fill:rgb(37,37,37)} -.Greys .q0-9{fill:rgb(255,255,255)} -.Greys .q1-9{fill:rgb(240,240,240)} -.Greys .q2-9{fill:rgb(217,217,217)} -.Greys .q3-9{fill:rgb(189,189,189)} -.Greys .q4-9{fill:rgb(150,150,150)} -.Greys .q5-9{fill:rgb(115,115,115)} -.Greys .q6-9{fill:rgb(82,82,82)} -.Greys .q7-9{fill:rgb(37,37,37)} -.Greys .q8-9{fill:rgb(0,0,0)} -.PuOr .q0-3{fill:rgb(241,163,64)} -.PuOr .q1-3{fill:rgb(247,247,247)} -.PuOr .q2-3{fill:rgb(153,142,195)} -.PuOr .q0-4{fill:rgb(230,97,1)} -.PuOr .q1-4{fill:rgb(253,184,99)} -.PuOr .q2-4{fill:rgb(178,171,210)} -.PuOr .q3-4{fill:rgb(94,60,153)} -.PuOr .q0-5{fill:rgb(230,97,1)} -.PuOr .q1-5{fill:rgb(253,184,99)} -.PuOr .q2-5{fill:rgb(247,247,247)} -.PuOr .q3-5{fill:rgb(178,171,210)} -.PuOr .q4-5{fill:rgb(94,60,153)} -.PuOr .q0-6{fill:rgb(179,88,6)} -.PuOr .q1-6{fill:rgb(241,163,64)} -.PuOr .q2-6{fill:rgb(254,224,182)} -.PuOr .q3-6{fill:rgb(216,218,235)} -.PuOr .q4-6{fill:rgb(153,142,195)} -.PuOr .q5-6{fill:rgb(84,39,136)} -.PuOr .q0-7{fill:rgb(179,88,6)} -.PuOr .q1-7{fill:rgb(241,163,64)} -.PuOr .q2-7{fill:rgb(254,224,182)} -.PuOr .q3-7{fill:rgb(247,247,247)} -.PuOr .q4-7{fill:rgb(216,218,235)} -.PuOr .q5-7{fill:rgb(153,142,195)} -.PuOr .q6-7{fill:rgb(84,39,136)} -.PuOr .q0-8{fill:rgb(179,88,6)} -.PuOr .q1-8{fill:rgb(224,130,20)} -.PuOr .q2-8{fill:rgb(253,184,99)} -.PuOr .q3-8{fill:rgb(254,224,182)} -.PuOr .q4-8{fill:rgb(216,218,235)} -.PuOr .q5-8{fill:rgb(178,171,210)} -.PuOr .q6-8{fill:rgb(128,115,172)} -.PuOr .q7-8{fill:rgb(84,39,136)} -.PuOr .q0-9{fill:rgb(179,88,6)} -.PuOr .q1-9{fill:rgb(224,130,20)} -.PuOr .q2-9{fill:rgb(253,184,99)} -.PuOr .q3-9{fill:rgb(254,224,182)} -.PuOr .q4-9{fill:rgb(247,247,247)} -.PuOr .q5-9{fill:rgb(216,218,235)} -.PuOr .q6-9{fill:rgb(178,171,210)} -.PuOr .q7-9{fill:rgb(128,115,172)} -.PuOr .q8-9{fill:rgb(84,39,136)} -.PuOr .q0-10{fill:rgb(127,59,8)} -.PuOr .q1-10{fill:rgb(179,88,6)} -.PuOr .q2-10{fill:rgb(224,130,20)} -.PuOr .q3-10{fill:rgb(253,184,99)} -.PuOr .q4-10{fill:rgb(254,224,182)} -.PuOr .q5-10{fill:rgb(216,218,235)} -.PuOr .q6-10{fill:rgb(178,171,210)} -.PuOr .q7-10{fill:rgb(128,115,172)} -.PuOr .q8-10{fill:rgb(84,39,136)} -.PuOr .q9-10{fill:rgb(45,0,75)} -.PuOr .q0-11{fill:rgb(127,59,8)} -.PuOr .q1-11{fill:rgb(179,88,6)} -.PuOr .q2-11{fill:rgb(224,130,20)} -.PuOr .q3-11{fill:rgb(253,184,99)} -.PuOr .q4-11{fill:rgb(254,224,182)} -.PuOr .q5-11{fill:rgb(247,247,247)} -.PuOr .q6-11{fill:rgb(216,218,235)} -.PuOr .q7-11{fill:rgb(178,171,210)} -.PuOr .q8-11{fill:rgb(128,115,172)} -.PuOr .q9-11{fill:rgb(84,39,136)} -.PuOr .q10-11{fill:rgb(45,0,75)} -.BrBG .q0-3{fill:rgb(216,179,101)} -.BrBG .q1-3{fill:rgb(245,245,245)} -.BrBG .q2-3{fill:rgb(90,180,172)} -.BrBG .q0-4{fill:rgb(166,97,26)} -.BrBG .q1-4{fill:rgb(223,194,125)} -.BrBG .q2-4{fill:rgb(128,205,193)} -.BrBG .q3-4{fill:rgb(1,133,113)} -.BrBG .q0-5{fill:rgb(166,97,26)} -.BrBG .q1-5{fill:rgb(223,194,125)} -.BrBG .q2-5{fill:rgb(245,245,245)} -.BrBG .q3-5{fill:rgb(128,205,193)} -.BrBG .q4-5{fill:rgb(1,133,113)} -.BrBG .q0-6{fill:rgb(140,81,10)} -.BrBG .q1-6{fill:rgb(216,179,101)} -.BrBG .q2-6{fill:rgb(246,232,195)} -.BrBG .q3-6{fill:rgb(199,234,229)} -.BrBG .q4-6{fill:rgb(90,180,172)} -.BrBG .q5-6{fill:rgb(1,102,94)} -.BrBG .q0-7{fill:rgb(140,81,10)} -.BrBG .q1-7{fill:rgb(216,179,101)} -.BrBG .q2-7{fill:rgb(246,232,195)} -.BrBG .q3-7{fill:rgb(245,245,245)} -.BrBG .q4-7{fill:rgb(199,234,229)} -.BrBG .q5-7{fill:rgb(90,180,172)} -.BrBG .q6-7{fill:rgb(1,102,94)} -.BrBG .q0-8{fill:rgb(140,81,10)} -.BrBG .q1-8{fill:rgb(191,129,45)} -.BrBG .q2-8{fill:rgb(223,194,125)} -.BrBG .q3-8{fill:rgb(246,232,195)} -.BrBG .q4-8{fill:rgb(199,234,229)} -.BrBG .q5-8{fill:rgb(128,205,193)} -.BrBG .q6-8{fill:rgb(53,151,143)} -.BrBG .q7-8{fill:rgb(1,102,94)} -.BrBG .q0-9{fill:rgb(140,81,10)} -.BrBG .q1-9{fill:rgb(191,129,45)} -.BrBG .q2-9{fill:rgb(223,194,125)} -.BrBG .q3-9{fill:rgb(246,232,195)} -.BrBG .q4-9{fill:rgb(245,245,245)} -.BrBG .q5-9{fill:rgb(199,234,229)} -.BrBG .q6-9{fill:rgb(128,205,193)} -.BrBG .q7-9{fill:rgb(53,151,143)} -.BrBG .q8-9{fill:rgb(1,102,94)} -.BrBG .q0-10{fill:rgb(84,48,5)} -.BrBG .q1-10{fill:rgb(140,81,10)} -.BrBG .q2-10{fill:rgb(191,129,45)} -.BrBG .q3-10{fill:rgb(223,194,125)} -.BrBG .q4-10{fill:rgb(246,232,195)} -.BrBG .q5-10{fill:rgb(199,234,229)} -.BrBG .q6-10{fill:rgb(128,205,193)} -.BrBG .q7-10{fill:rgb(53,151,143)} -.BrBG .q8-10{fill:rgb(1,102,94)} -.BrBG .q9-10{fill:rgb(0,60,48)} -.BrBG .q0-11{fill:rgb(84,48,5)} -.BrBG .q1-11{fill:rgb(140,81,10)} -.BrBG .q2-11{fill:rgb(191,129,45)} -.BrBG .q3-11{fill:rgb(223,194,125)} -.BrBG .q4-11{fill:rgb(246,232,195)} -.BrBG .q5-11{fill:rgb(245,245,245)} -.BrBG .q6-11{fill:rgb(199,234,229)} -.BrBG .q7-11{fill:rgb(128,205,193)} -.BrBG .q8-11{fill:rgb(53,151,143)} -.BrBG .q9-11{fill:rgb(1,102,94)} -.BrBG .q10-11{fill:rgb(0,60,48)} -.PRGn .q0-3{fill:rgb(175,141,195)} -.PRGn .q1-3{fill:rgb(247,247,247)} -.PRGn .q2-3{fill:rgb(127,191,123)} -.PRGn .q0-4{fill:rgb(123,50,148)} -.PRGn .q1-4{fill:rgb(194,165,207)} -.PRGn .q2-4{fill:rgb(166,219,160)} -.PRGn .q3-4{fill:rgb(0,136,55)} -.PRGn .q0-5{fill:rgb(123,50,148)} -.PRGn .q1-5{fill:rgb(194,165,207)} -.PRGn .q2-5{fill:rgb(247,247,247)} -.PRGn .q3-5{fill:rgb(166,219,160)} -.PRGn .q4-5{fill:rgb(0,136,55)} -.PRGn .q0-6{fill:rgb(118,42,131)} -.PRGn .q1-6{fill:rgb(175,141,195)} -.PRGn .q2-6{fill:rgb(231,212,232)} -.PRGn .q3-6{fill:rgb(217,240,211)} -.PRGn .q4-6{fill:rgb(127,191,123)} -.PRGn .q5-6{fill:rgb(27,120,55)} -.PRGn .q0-7{fill:rgb(118,42,131)} -.PRGn .q1-7{fill:rgb(175,141,195)} -.PRGn .q2-7{fill:rgb(231,212,232)} -.PRGn .q3-7{fill:rgb(247,247,247)} -.PRGn .q4-7{fill:rgb(217,240,211)} -.PRGn .q5-7{fill:rgb(127,191,123)} -.PRGn .q6-7{fill:rgb(27,120,55)} -.PRGn .q0-8{fill:rgb(118,42,131)} -.PRGn .q1-8{fill:rgb(153,112,171)} -.PRGn .q2-8{fill:rgb(194,165,207)} -.PRGn .q3-8{fill:rgb(231,212,232)} -.PRGn .q4-8{fill:rgb(217,240,211)} -.PRGn .q5-8{fill:rgb(166,219,160)} -.PRGn .q6-8{fill:rgb(90,174,97)} -.PRGn .q7-8{fill:rgb(27,120,55)} -.PRGn .q0-9{fill:rgb(118,42,131)} -.PRGn .q1-9{fill:rgb(153,112,171)} -.PRGn .q2-9{fill:rgb(194,165,207)} -.PRGn .q3-9{fill:rgb(231,212,232)} -.PRGn .q4-9{fill:rgb(247,247,247)} -.PRGn .q5-9{fill:rgb(217,240,211)} -.PRGn .q6-9{fill:rgb(166,219,160)} -.PRGn .q7-9{fill:rgb(90,174,97)} -.PRGn .q8-9{fill:rgb(27,120,55)} -.PRGn .q0-10{fill:rgb(64,0,75)} -.PRGn .q1-10{fill:rgb(118,42,131)} -.PRGn .q2-10{fill:rgb(153,112,171)} -.PRGn .q3-10{fill:rgb(194,165,207)} -.PRGn .q4-10{fill:rgb(231,212,232)} -.PRGn .q5-10{fill:rgb(217,240,211)} -.PRGn .q6-10{fill:rgb(166,219,160)} -.PRGn .q7-10{fill:rgb(90,174,97)} -.PRGn .q8-10{fill:rgb(27,120,55)} -.PRGn .q9-10{fill:rgb(0,68,27)} -.PRGn .q0-11{fill:rgb(64,0,75)} -.PRGn .q1-11{fill:rgb(118,42,131)} -.PRGn .q2-11{fill:rgb(153,112,171)} -.PRGn .q3-11{fill:rgb(194,165,207)} -.PRGn .q4-11{fill:rgb(231,212,232)} -.PRGn .q5-11{fill:rgb(247,247,247)} -.PRGn .q6-11{fill:rgb(217,240,211)} -.PRGn .q7-11{fill:rgb(166,219,160)} -.PRGn .q8-11{fill:rgb(90,174,97)} -.PRGn .q9-11{fill:rgb(27,120,55)} -.PRGn .q10-11{fill:rgb(0,68,27)} -.PiYG .q0-3{fill:rgb(233,163,201)} -.PiYG .q1-3{fill:rgb(247,247,247)} -.PiYG .q2-3{fill:rgb(161,215,106)} -.PiYG .q0-4{fill:rgb(208,28,139)} -.PiYG .q1-4{fill:rgb(241,182,218)} -.PiYG .q2-4{fill:rgb(184,225,134)} -.PiYG .q3-4{fill:rgb(77,172,38)} -.PiYG .q0-5{fill:rgb(208,28,139)} -.PiYG .q1-5{fill:rgb(241,182,218)} -.PiYG .q2-5{fill:rgb(247,247,247)} -.PiYG .q3-5{fill:rgb(184,225,134)} -.PiYG .q4-5{fill:rgb(77,172,38)} -.PiYG .q0-6{fill:rgb(197,27,125)} -.PiYG .q1-6{fill:rgb(233,163,201)} -.PiYG .q2-6{fill:rgb(253,224,239)} -.PiYG .q3-6{fill:rgb(230,245,208)} -.PiYG .q4-6{fill:rgb(161,215,106)} -.PiYG .q5-6{fill:rgb(77,146,33)} -.PiYG .q0-7{fill:rgb(197,27,125)} -.PiYG .q1-7{fill:rgb(233,163,201)} -.PiYG .q2-7{fill:rgb(253,224,239)} -.PiYG .q3-7{fill:rgb(247,247,247)} -.PiYG .q4-7{fill:rgb(230,245,208)} -.PiYG .q5-7{fill:rgb(161,215,106)} -.PiYG .q6-7{fill:rgb(77,146,33)} -.PiYG .q0-8{fill:rgb(197,27,125)} -.PiYG .q1-8{fill:rgb(222,119,174)} -.PiYG .q2-8{fill:rgb(241,182,218)} -.PiYG .q3-8{fill:rgb(253,224,239)} -.PiYG .q4-8{fill:rgb(230,245,208)} -.PiYG .q5-8{fill:rgb(184,225,134)} -.PiYG .q6-8{fill:rgb(127,188,65)} -.PiYG .q7-8{fill:rgb(77,146,33)} -.PiYG .q0-9{fill:rgb(197,27,125)} -.PiYG .q1-9{fill:rgb(222,119,174)} -.PiYG .q2-9{fill:rgb(241,182,218)} -.PiYG .q3-9{fill:rgb(253,224,239)} -.PiYG .q4-9{fill:rgb(247,247,247)} -.PiYG .q5-9{fill:rgb(230,245,208)} -.PiYG .q6-9{fill:rgb(184,225,134)} -.PiYG .q7-9{fill:rgb(127,188,65)} -.PiYG .q8-9{fill:rgb(77,146,33)} -.PiYG .q0-10{fill:rgb(142,1,82)} -.PiYG .q1-10{fill:rgb(197,27,125)} -.PiYG .q2-10{fill:rgb(222,119,174)} -.PiYG .q3-10{fill:rgb(241,182,218)} -.PiYG .q4-10{fill:rgb(253,224,239)} -.PiYG .q5-10{fill:rgb(230,245,208)} -.PiYG .q6-10{fill:rgb(184,225,134)} -.PiYG .q7-10{fill:rgb(127,188,65)} -.PiYG .q8-10{fill:rgb(77,146,33)} -.PiYG .q9-10{fill:rgb(39,100,25)} -.PiYG .q0-11{fill:rgb(142,1,82)} -.PiYG .q1-11{fill:rgb(197,27,125)} -.PiYG .q2-11{fill:rgb(222,119,174)} -.PiYG .q3-11{fill:rgb(241,182,218)} -.PiYG .q4-11{fill:rgb(253,224,239)} -.PiYG .q5-11{fill:rgb(247,247,247)} -.PiYG .q6-11{fill:rgb(230,245,208)} -.PiYG .q7-11{fill:rgb(184,225,134)} -.PiYG .q8-11{fill:rgb(127,188,65)} -.PiYG .q9-11{fill:rgb(77,146,33)} -.PiYG .q10-11{fill:rgb(39,100,25)} -.RdBu .q0-3{fill:rgb(239,138,98)} -.RdBu .q1-3{fill:rgb(247,247,247)} -.RdBu .q2-3{fill:rgb(103,169,207)} -.RdBu .q0-4{fill:rgb(202,0,32)} -.RdBu .q1-4{fill:rgb(244,165,130)} -.RdBu .q2-4{fill:rgb(146,197,222)} -.RdBu .q3-4{fill:rgb(5,113,176)} -.RdBu .q0-5{fill:rgb(202,0,32)} -.RdBu .q1-5{fill:rgb(244,165,130)} -.RdBu .q2-5{fill:rgb(247,247,247)} -.RdBu .q3-5{fill:rgb(146,197,222)} -.RdBu .q4-5{fill:rgb(5,113,176)} -.RdBu .q0-6{fill:rgb(178,24,43)} -.RdBu .q1-6{fill:rgb(239,138,98)} -.RdBu .q2-6{fill:rgb(253,219,199)} -.RdBu .q3-6{fill:rgb(209,229,240)} -.RdBu .q4-6{fill:rgb(103,169,207)} -.RdBu .q5-6{fill:rgb(33,102,172)} -.RdBu .q0-7{fill:rgb(178,24,43)} -.RdBu .q1-7{fill:rgb(239,138,98)} -.RdBu .q2-7{fill:rgb(253,219,199)} -.RdBu .q3-7{fill:rgb(247,247,247)} -.RdBu .q4-7{fill:rgb(209,229,240)} -.RdBu .q5-7{fill:rgb(103,169,207)} -.RdBu .q6-7{fill:rgb(33,102,172)} -.RdBu .q0-8{fill:rgb(178,24,43)} -.RdBu .q1-8{fill:rgb(214,96,77)} -.RdBu .q2-8{fill:rgb(244,165,130)} -.RdBu .q3-8{fill:rgb(253,219,199)} -.RdBu .q4-8{fill:rgb(209,229,240)} -.RdBu .q5-8{fill:rgb(146,197,222)} -.RdBu .q6-8{fill:rgb(67,147,195)} -.RdBu .q7-8{fill:rgb(33,102,172)} -.RdBu .q0-9{fill:rgb(178,24,43)} -.RdBu .q1-9{fill:rgb(214,96,77)} -.RdBu .q2-9{fill:rgb(244,165,130)} -.RdBu .q3-9{fill:rgb(253,219,199)} -.RdBu .q4-9{fill:rgb(247,247,247)} -.RdBu .q5-9{fill:rgb(209,229,240)} -.RdBu .q6-9{fill:rgb(146,197,222)} -.RdBu .q7-9{fill:rgb(67,147,195)} -.RdBu .q8-9{fill:rgb(33,102,172)} -.RdBu .q0-10{fill:rgb(103,0,31)} -.RdBu .q1-10{fill:rgb(178,24,43)} -.RdBu .q2-10{fill:rgb(214,96,77)} -.RdBu .q3-10{fill:rgb(244,165,130)} -.RdBu .q4-10{fill:rgb(253,219,199)} -.RdBu .q5-10{fill:rgb(209,229,240)} -.RdBu .q6-10{fill:rgb(146,197,222)} -.RdBu .q7-10{fill:rgb(67,147,195)} -.RdBu .q8-10{fill:rgb(33,102,172)} -.RdBu .q9-10{fill:rgb(5,48,97)} -.RdBu .q0-11{fill:rgb(103,0,31)} -.RdBu .q1-11{fill:rgb(178,24,43)} -.RdBu .q2-11{fill:rgb(214,96,77)} -.RdBu .q3-11{fill:rgb(244,165,130)} -.RdBu .q4-11{fill:rgb(253,219,199)} -.RdBu .q5-11{fill:rgb(247,247,247)} -.RdBu .q6-11{fill:rgb(209,229,240)} -.RdBu .q7-11{fill:rgb(146,197,222)} -.RdBu .q8-11{fill:rgb(67,147,195)} -.RdBu .q9-11{fill:rgb(33,102,172)} -.RdBu .q10-11{fill:rgb(5,48,97)} -.RdGy .q0-3{fill:rgb(239,138,98)} -.RdGy .q1-3{fill:rgb(255,255,255)} -.RdGy .q2-3{fill:rgb(153,153,153)} -.RdGy .q0-4{fill:rgb(202,0,32)} -.RdGy .q1-4{fill:rgb(244,165,130)} -.RdGy .q2-4{fill:rgb(186,186,186)} -.RdGy .q3-4{fill:rgb(64,64,64)} -.RdGy .q0-5{fill:rgb(202,0,32)} -.RdGy .q1-5{fill:rgb(244,165,130)} -.RdGy .q2-5{fill:rgb(255,255,255)} -.RdGy .q3-5{fill:rgb(186,186,186)} -.RdGy .q4-5{fill:rgb(64,64,64)} -.RdGy .q0-6{fill:rgb(178,24,43)} -.RdGy .q1-6{fill:rgb(239,138,98)} -.RdGy .q2-6{fill:rgb(253,219,199)} -.RdGy .q3-6{fill:rgb(224,224,224)} -.RdGy .q4-6{fill:rgb(153,153,153)} -.RdGy .q5-6{fill:rgb(77,77,77)} -.RdGy .q0-7{fill:rgb(178,24,43)} -.RdGy .q1-7{fill:rgb(239,138,98)} -.RdGy .q2-7{fill:rgb(253,219,199)} -.RdGy .q3-7{fill:rgb(255,255,255)} -.RdGy .q4-7{fill:rgb(224,224,224)} -.RdGy .q5-7{fill:rgb(153,153,153)} -.RdGy .q6-7{fill:rgb(77,77,77)} -.RdGy .q0-8{fill:rgb(178,24,43)} -.RdGy .q1-8{fill:rgb(214,96,77)} -.RdGy .q2-8{fill:rgb(244,165,130)} -.RdGy .q3-8{fill:rgb(253,219,199)} -.RdGy .q4-8{fill:rgb(224,224,224)} -.RdGy .q5-8{fill:rgb(186,186,186)} -.RdGy .q6-8{fill:rgb(135,135,135)} -.RdGy .q7-8{fill:rgb(77,77,77)} -.RdGy .q0-9{fill:rgb(178,24,43)} -.RdGy .q1-9{fill:rgb(214,96,77)} -.RdGy .q2-9{fill:rgb(244,165,130)} -.RdGy .q3-9{fill:rgb(253,219,199)} -.RdGy .q4-9{fill:rgb(255,255,255)} -.RdGy .q5-9{fill:rgb(224,224,224)} -.RdGy .q6-9{fill:rgb(186,186,186)} -.RdGy .q7-9{fill:rgb(135,135,135)} -.RdGy .q8-9{fill:rgb(77,77,77)} -.RdGy .q0-10{fill:rgb(103,0,31)} -.RdGy .q1-10{fill:rgb(178,24,43)} -.RdGy .q2-10{fill:rgb(214,96,77)} -.RdGy .q3-10{fill:rgb(244,165,130)} -.RdGy .q4-10{fill:rgb(253,219,199)} -.RdGy .q5-10{fill:rgb(224,224,224)} -.RdGy .q6-10{fill:rgb(186,186,186)} -.RdGy .q7-10{fill:rgb(135,135,135)} -.RdGy .q8-10{fill:rgb(77,77,77)} -.RdGy .q9-10{fill:rgb(26,26,26)} -.RdGy .q0-11{fill:rgb(103,0,31)} -.RdGy .q1-11{fill:rgb(178,24,43)} -.RdGy .q2-11{fill:rgb(214,96,77)} -.RdGy .q3-11{fill:rgb(244,165,130)} -.RdGy .q4-11{fill:rgb(253,219,199)} -.RdGy .q5-11{fill:rgb(255,255,255)} -.RdGy .q6-11{fill:rgb(224,224,224)} -.RdGy .q7-11{fill:rgb(186,186,186)} -.RdGy .q8-11{fill:rgb(135,135,135)} -.RdGy .q9-11{fill:rgb(77,77,77)} -.RdGy .q10-11{fill:rgb(26,26,26)} -.RdYlBu .q0-3{fill:rgb(252,141,89)} -.RdYlBu .q1-3{fill:rgb(255,255,191)} -.RdYlBu .q2-3{fill:rgb(145,191,219)} -.RdYlBu .q0-4{fill:rgb(215,25,28)} -.RdYlBu .q1-4{fill:rgb(253,174,97)} -.RdYlBu .q2-4{fill:rgb(171,217,233)} -.RdYlBu .q3-4{fill:rgb(44,123,182)} -.RdYlBu .q0-5{fill:rgb(215,25,28)} -.RdYlBu .q1-5{fill:rgb(253,174,97)} -.RdYlBu .q2-5{fill:rgb(255,255,191)} -.RdYlBu .q3-5{fill:rgb(171,217,233)} -.RdYlBu .q4-5{fill:rgb(44,123,182)} -.RdYlBu .q0-6{fill:rgb(215,48,39)} -.RdYlBu .q1-6{fill:rgb(252,141,89)} -.RdYlBu .q2-6{fill:rgb(254,224,144)} -.RdYlBu .q3-6{fill:rgb(224,243,248)} -.RdYlBu .q4-6{fill:rgb(145,191,219)} -.RdYlBu .q5-6{fill:rgb(69,117,180)} -.RdYlBu .q0-7{fill:rgb(215,48,39)} -.RdYlBu .q1-7{fill:rgb(252,141,89)} -.RdYlBu .q2-7{fill:rgb(254,224,144)} -.RdYlBu .q3-7{fill:rgb(255,255,191)} -.RdYlBu .q4-7{fill:rgb(224,243,248)} -.RdYlBu .q5-7{fill:rgb(145,191,219)} -.RdYlBu .q6-7{fill:rgb(69,117,180)} -.RdYlBu .q0-8{fill:rgb(215,48,39)} -.RdYlBu .q1-8{fill:rgb(244,109,67)} -.RdYlBu .q2-8{fill:rgb(253,174,97)} -.RdYlBu .q3-8{fill:rgb(254,224,144)} -.RdYlBu .q4-8{fill:rgb(224,243,248)} -.RdYlBu .q5-8{fill:rgb(171,217,233)} -.RdYlBu .q6-8{fill:rgb(116,173,209)} -.RdYlBu .q7-8{fill:rgb(69,117,180)} -.RdYlBu .q0-9{fill:rgb(215,48,39)} -.RdYlBu .q1-9{fill:rgb(244,109,67)} -.RdYlBu .q2-9{fill:rgb(253,174,97)} -.RdYlBu .q3-9{fill:rgb(254,224,144)} -.RdYlBu .q4-9{fill:rgb(255,255,191)} -.RdYlBu .q5-9{fill:rgb(224,243,248)} -.RdYlBu .q6-9{fill:rgb(171,217,233)} -.RdYlBu .q7-9{fill:rgb(116,173,209)} -.RdYlBu .q8-9{fill:rgb(69,117,180)} -.RdYlBu .q0-10{fill:rgb(165,0,38)} -.RdYlBu .q1-10{fill:rgb(215,48,39)} -.RdYlBu .q2-10{fill:rgb(244,109,67)} -.RdYlBu .q3-10{fill:rgb(253,174,97)} -.RdYlBu .q4-10{fill:rgb(254,224,144)} -.RdYlBu .q5-10{fill:rgb(224,243,248)} -.RdYlBu .q6-10{fill:rgb(171,217,233)} -.RdYlBu .q7-10{fill:rgb(116,173,209)} -.RdYlBu .q8-10{fill:rgb(69,117,180)} -.RdYlBu .q9-10{fill:rgb(49,54,149)} -.RdYlBu .q0-11{fill:rgb(165,0,38)} -.RdYlBu .q1-11{fill:rgb(215,48,39)} -.RdYlBu .q2-11{fill:rgb(244,109,67)} -.RdYlBu .q3-11{fill:rgb(253,174,97)} -.RdYlBu .q4-11{fill:rgb(254,224,144)} -.RdYlBu .q5-11{fill:rgb(255,255,191)} -.RdYlBu .q6-11{fill:rgb(224,243,248)} -.RdYlBu .q7-11{fill:rgb(171,217,233)} -.RdYlBu .q8-11{fill:rgb(116,173,209)} -.RdYlBu .q9-11{fill:rgb(69,117,180)} -.RdYlBu .q10-11{fill:rgb(49,54,149)} -.Spectral .q0-3{fill:rgb(252,141,89)} -.Spectral .q1-3{fill:rgb(255,255,191)} -.Spectral .q2-3{fill:rgb(153,213,148)} -.Spectral .q0-4{fill:rgb(215,25,28)} -.Spectral .q1-4{fill:rgb(253,174,97)} -.Spectral .q2-4{fill:rgb(171,221,164)} -.Spectral .q3-4{fill:rgb(43,131,186)} -.Spectral .q0-5{fill:rgb(215,25,28)} -.Spectral .q1-5{fill:rgb(253,174,97)} -.Spectral .q2-5{fill:rgb(255,255,191)} -.Spectral .q3-5{fill:rgb(171,221,164)} -.Spectral .q4-5{fill:rgb(43,131,186)} -.Spectral .q0-6{fill:rgb(213,62,79)} -.Spectral .q1-6{fill:rgb(252,141,89)} -.Spectral .q2-6{fill:rgb(254,224,139)} -.Spectral .q3-6{fill:rgb(230,245,152)} -.Spectral .q4-6{fill:rgb(153,213,148)} -.Spectral .q5-6{fill:rgb(50,136,189)} -.Spectral .q0-7{fill:rgb(213,62,79)} -.Spectral .q1-7{fill:rgb(252,141,89)} -.Spectral .q2-7{fill:rgb(254,224,139)} -.Spectral .q3-7{fill:rgb(255,255,191)} -.Spectral .q4-7{fill:rgb(230,245,152)} -.Spectral .q5-7{fill:rgb(153,213,148)} -.Spectral .q6-7{fill:rgb(50,136,189)} -.Spectral .q0-8{fill:rgb(213,62,79)} -.Spectral .q1-8{fill:rgb(244,109,67)} -.Spectral .q2-8{fill:rgb(253,174,97)} -.Spectral .q3-8{fill:rgb(254,224,139)} -.Spectral .q4-8{fill:rgb(230,245,152)} -.Spectral .q5-8{fill:rgb(171,221,164)} -.Spectral .q6-8{fill:rgb(102,194,165)} -.Spectral .q7-8{fill:rgb(50,136,189)} -.Spectral .q0-9{fill:rgb(213,62,79)} -.Spectral .q1-9{fill:rgb(244,109,67)} -.Spectral .q2-9{fill:rgb(253,174,97)} -.Spectral .q3-9{fill:rgb(254,224,139)} -.Spectral .q4-9{fill:rgb(255,255,191)} -.Spectral .q5-9{fill:rgb(230,245,152)} -.Spectral .q6-9{fill:rgb(171,221,164)} -.Spectral .q7-9{fill:rgb(102,194,165)} -.Spectral .q8-9{fill:rgb(50,136,189)} -.Spectral .q0-10{fill:rgb(158,1,66)} -.Spectral .q1-10{fill:rgb(213,62,79)} -.Spectral .q2-10{fill:rgb(244,109,67)} -.Spectral .q3-10{fill:rgb(253,174,97)} -.Spectral .q4-10{fill:rgb(254,224,139)} -.Spectral .q5-10{fill:rgb(230,245,152)} -.Spectral .q6-10{fill:rgb(171,221,164)} -.Spectral .q7-10{fill:rgb(102,194,165)} -.Spectral .q8-10{fill:rgb(50,136,189)} -.Spectral .q9-10{fill:rgb(94,79,162)} -.Spectral .q0-11{fill:rgb(158,1,66)} -.Spectral .q1-11{fill:rgb(213,62,79)} -.Spectral .q2-11{fill:rgb(244,109,67)} -.Spectral .q3-11{fill:rgb(253,174,97)} -.Spectral .q4-11{fill:rgb(254,224,139)} -.Spectral .q5-11{fill:rgb(255,255,191)} -.Spectral .q6-11{fill:rgb(230,245,152)} -.Spectral .q7-11{fill:rgb(171,221,164)} -.Spectral .q8-11{fill:rgb(102,194,165)} -.Spectral .q9-11{fill:rgb(50,136,189)} -.Spectral .q10-11{fill:rgb(94,79,162)} -.RdYlGn .q0-3{fill:rgb(252,141,89)} -.RdYlGn .q1-3{fill:rgb(255,255,191)} -.RdYlGn .q2-3{fill:rgb(145,207,96)} -.RdYlGn .q0-4{fill:rgb(215,25,28)} -.RdYlGn .q1-4{fill:rgb(253,174,97)} -.RdYlGn .q2-4{fill:rgb(166,217,106)} -.RdYlGn .q3-4{fill:rgb(26,150,65)} -.RdYlGn .q0-5{fill:rgb(215,25,28)} -.RdYlGn .q1-5{fill:rgb(253,174,97)} -.RdYlGn .q2-5{fill:rgb(255,255,191)} -.RdYlGn .q3-5{fill:rgb(166,217,106)} -.RdYlGn .q4-5{fill:rgb(26,150,65)} -.RdYlGn .q0-6{fill:rgb(215,48,39)} -.RdYlGn .q1-6{fill:rgb(252,141,89)} -.RdYlGn .q2-6{fill:rgb(254,224,139)} -.RdYlGn .q3-6{fill:rgb(217,239,139)} -.RdYlGn .q4-6{fill:rgb(145,207,96)} -.RdYlGn .q5-6{fill:rgb(26,152,80)} -.RdYlGn .q0-7{fill:rgb(215,48,39)} -.RdYlGn .q1-7{fill:rgb(252,141,89)} -.RdYlGn .q2-7{fill:rgb(254,224,139)} -.RdYlGn .q3-7{fill:rgb(255,255,191)} -.RdYlGn .q4-7{fill:rgb(217,239,139)} -.RdYlGn .q5-7{fill:rgb(145,207,96)} -.RdYlGn .q6-7{fill:rgb(26,152,80)} -.RdYlGn .q0-8{fill:rgb(215,48,39)} -.RdYlGn .q1-8{fill:rgb(244,109,67)} -.RdYlGn .q2-8{fill:rgb(253,174,97)} -.RdYlGn .q3-8{fill:rgb(254,224,139)} -.RdYlGn .q4-8{fill:rgb(217,239,139)} -.RdYlGn .q5-8{fill:rgb(166,217,106)} -.RdYlGn .q6-8{fill:rgb(102,189,99)} -.RdYlGn .q7-8{fill:rgb(26,152,80)} -.RdYlGn .q0-9{fill:rgb(215,48,39)} -.RdYlGn .q1-9{fill:rgb(244,109,67)} -.RdYlGn .q2-9{fill:rgb(253,174,97)} -.RdYlGn .q3-9{fill:rgb(254,224,139)} -.RdYlGn .q4-9{fill:rgb(255,255,191)} -.RdYlGn .q5-9{fill:rgb(217,239,139)} -.RdYlGn .q6-9{fill:rgb(166,217,106)} -.RdYlGn .q7-9{fill:rgb(102,189,99)} -.RdYlGn .q8-9{fill:rgb(26,152,80)} -.RdYlGn .q0-10{fill:rgb(165,0,38)} -.RdYlGn .q1-10{fill:rgb(215,48,39)} -.RdYlGn .q2-10{fill:rgb(244,109,67)} -.RdYlGn .q3-10{fill:rgb(253,174,97)} -.RdYlGn .q4-10{fill:rgb(254,224,139)} -.RdYlGn .q5-10{fill:rgb(217,239,139)} -.RdYlGn .q6-10{fill:rgb(166,217,106)} -.RdYlGn .q7-10{fill:rgb(102,189,99)} -.RdYlGn .q8-10{fill:rgb(26,152,80)} -.RdYlGn .q9-10{fill:rgb(0,104,55)} -.RdYlGn .q0-11{fill:rgb(165,0,38)} -.RdYlGn .q1-11{fill:rgb(215,48,39)} -.RdYlGn .q2-11{fill:rgb(244,109,67)} -.RdYlGn .q3-11{fill:rgb(253,174,97)} -.RdYlGn .q4-11{fill:rgb(254,224,139)} -.RdYlGn .q5-11{fill:rgb(255,255,191)} -.RdYlGn .q6-11{fill:rgb(217,239,139)} -.RdYlGn .q7-11{fill:rgb(166,217,106)} -.RdYlGn .q8-11{fill:rgb(102,189,99)} -.RdYlGn .q9-11{fill:rgb(26,152,80)} -.RdYlGn .q10-11{fill:rgb(0,104,55)} -.Accent .q0-3{fill:rgb(127,201,127)} -.Accent .q1-3{fill:rgb(190,174,212)} -.Accent .q2-3{fill:rgb(253,192,134)} -.Accent .q0-4{fill:rgb(127,201,127)} -.Accent .q1-4{fill:rgb(190,174,212)} -.Accent .q2-4{fill:rgb(253,192,134)} -.Accent .q3-4{fill:rgb(255,255,153)} -.Accent .q0-5{fill:rgb(127,201,127)} -.Accent .q1-5{fill:rgb(190,174,212)} -.Accent .q2-5{fill:rgb(253,192,134)} -.Accent .q3-5{fill:rgb(255,255,153)} -.Accent .q4-5{fill:rgb(56,108,176)} -.Accent .q0-6{fill:rgb(127,201,127)} -.Accent .q1-6{fill:rgb(190,174,212)} -.Accent .q2-6{fill:rgb(253,192,134)} -.Accent .q3-6{fill:rgb(255,255,153)} -.Accent .q4-6{fill:rgb(56,108,176)} -.Accent .q5-6{fill:rgb(240,2,127)} -.Accent .q0-7{fill:rgb(127,201,127)} -.Accent .q1-7{fill:rgb(190,174,212)} -.Accent .q2-7{fill:rgb(253,192,134)} -.Accent .q3-7{fill:rgb(255,255,153)} -.Accent .q4-7{fill:rgb(56,108,176)} -.Accent .q5-7{fill:rgb(240,2,127)} -.Accent .q6-7{fill:rgb(191,91,23)} -.Accent .q0-8{fill:rgb(127,201,127)} -.Accent .q1-8{fill:rgb(190,174,212)} -.Accent .q2-8{fill:rgb(253,192,134)} -.Accent .q3-8{fill:rgb(255,255,153)} -.Accent .q4-8{fill:rgb(56,108,176)} -.Accent .q5-8{fill:rgb(240,2,127)} -.Accent .q6-8{fill:rgb(191,91,23)} -.Accent .q7-8{fill:rgb(102,102,102)} -.Dark2 .q0-3{fill:rgb(27,158,119)} -.Dark2 .q1-3{fill:rgb(217,95,2)} -.Dark2 .q2-3{fill:rgb(117,112,179)} -.Dark2 .q0-4{fill:rgb(27,158,119)} -.Dark2 .q1-4{fill:rgb(217,95,2)} -.Dark2 .q2-4{fill:rgb(117,112,179)} -.Dark2 .q3-4{fill:rgb(231,41,138)} -.Dark2 .q0-5{fill:rgb(27,158,119)} -.Dark2 .q1-5{fill:rgb(217,95,2)} -.Dark2 .q2-5{fill:rgb(117,112,179)} -.Dark2 .q3-5{fill:rgb(231,41,138)} -.Dark2 .q4-5{fill:rgb(102,166,30)} -.Dark2 .q0-6{fill:rgb(27,158,119)} -.Dark2 .q1-6{fill:rgb(217,95,2)} -.Dark2 .q2-6{fill:rgb(117,112,179)} -.Dark2 .q3-6{fill:rgb(231,41,138)} -.Dark2 .q4-6{fill:rgb(102,166,30)} -.Dark2 .q5-6{fill:rgb(230,171,2)} -.Dark2 .q0-7{fill:rgb(27,158,119)} -.Dark2 .q1-7{fill:rgb(217,95,2)} -.Dark2 .q2-7{fill:rgb(117,112,179)} -.Dark2 .q3-7{fill:rgb(231,41,138)} -.Dark2 .q4-7{fill:rgb(102,166,30)} -.Dark2 .q5-7{fill:rgb(230,171,2)} -.Dark2 .q6-7{fill:rgb(166,118,29)} -.Dark2 .q0-8{fill:rgb(27,158,119)} -.Dark2 .q1-8{fill:rgb(217,95,2)} -.Dark2 .q2-8{fill:rgb(117,112,179)} -.Dark2 .q3-8{fill:rgb(231,41,138)} -.Dark2 .q4-8{fill:rgb(102,166,30)} -.Dark2 .q5-8{fill:rgb(230,171,2)} -.Dark2 .q6-8{fill:rgb(166,118,29)} -.Dark2 .q7-8{fill:rgb(102,102,102)} -.Paired .q0-3{fill:rgb(166,206,227)} -.Paired .q1-3{fill:rgb(31,120,180)} -.Paired .q2-3{fill:rgb(178,223,138)} -.Paired .q0-4{fill:rgb(166,206,227)} -.Paired .q1-4{fill:rgb(31,120,180)} -.Paired .q2-4{fill:rgb(178,223,138)} -.Paired .q3-4{fill:rgb(51,160,44)} -.Paired .q0-5{fill:rgb(166,206,227)} -.Paired .q1-5{fill:rgb(31,120,180)} -.Paired .q2-5{fill:rgb(178,223,138)} -.Paired .q3-5{fill:rgb(51,160,44)} -.Paired .q4-5{fill:rgb(251,154,153)} -.Paired .q0-6{fill:rgb(166,206,227)} -.Paired .q1-6{fill:rgb(31,120,180)} -.Paired .q2-6{fill:rgb(178,223,138)} -.Paired .q3-6{fill:rgb(51,160,44)} -.Paired .q4-6{fill:rgb(251,154,153)} -.Paired .q5-6{fill:rgb(227,26,28)} -.Paired .q0-7{fill:rgb(166,206,227)} -.Paired .q1-7{fill:rgb(31,120,180)} -.Paired .q2-7{fill:rgb(178,223,138)} -.Paired .q3-7{fill:rgb(51,160,44)} -.Paired .q4-7{fill:rgb(251,154,153)} -.Paired .q5-7{fill:rgb(227,26,28)} -.Paired .q6-7{fill:rgb(253,191,111)} -.Paired .q0-8{fill:rgb(166,206,227)} -.Paired .q1-8{fill:rgb(31,120,180)} -.Paired .q2-8{fill:rgb(178,223,138)} -.Paired .q3-8{fill:rgb(51,160,44)} -.Paired .q4-8{fill:rgb(251,154,153)} -.Paired .q5-8{fill:rgb(227,26,28)} -.Paired .q6-8{fill:rgb(253,191,111)} -.Paired .q7-8{fill:rgb(255,127,0)} -.Paired .q0-9{fill:rgb(166,206,227)} -.Paired .q1-9{fill:rgb(31,120,180)} -.Paired .q2-9{fill:rgb(178,223,138)} -.Paired .q3-9{fill:rgb(51,160,44)} -.Paired .q4-9{fill:rgb(251,154,153)} -.Paired .q5-9{fill:rgb(227,26,28)} -.Paired .q6-9{fill:rgb(253,191,111)} -.Paired .q7-9{fill:rgb(255,127,0)} -.Paired .q8-9{fill:rgb(202,178,214)} -.Paired .q0-10{fill:rgb(166,206,227)} -.Paired .q1-10{fill:rgb(31,120,180)} -.Paired .q2-10{fill:rgb(178,223,138)} -.Paired .q3-10{fill:rgb(51,160,44)} -.Paired .q4-10{fill:rgb(251,154,153)} -.Paired .q5-10{fill:rgb(227,26,28)} -.Paired .q6-10{fill:rgb(253,191,111)} -.Paired .q7-10{fill:rgb(255,127,0)} -.Paired .q8-10{fill:rgb(202,178,214)} -.Paired .q9-10{fill:rgb(106,61,154)} -.Paired .q0-11{fill:rgb(166,206,227)} -.Paired .q1-11{fill:rgb(31,120,180)} -.Paired .q2-11{fill:rgb(178,223,138)} -.Paired .q3-11{fill:rgb(51,160,44)} -.Paired .q4-11{fill:rgb(251,154,153)} -.Paired .q5-11{fill:rgb(227,26,28)} -.Paired .q6-11{fill:rgb(253,191,111)} -.Paired .q7-11{fill:rgb(255,127,0)} -.Paired .q8-11{fill:rgb(202,178,214)} -.Paired .q9-11{fill:rgb(106,61,154)} -.Paired .q10-11{fill:rgb(255,255,153)} -.Paired .q0-12{fill:rgb(166,206,227)} -.Paired .q1-12{fill:rgb(31,120,180)} -.Paired .q2-12{fill:rgb(178,223,138)} -.Paired .q3-12{fill:rgb(51,160,44)} -.Paired .q4-12{fill:rgb(251,154,153)} -.Paired .q5-12{fill:rgb(227,26,28)} -.Paired .q6-12{fill:rgb(253,191,111)} -.Paired .q7-12{fill:rgb(255,127,0)} -.Paired .q8-12{fill:rgb(202,178,214)} -.Paired .q9-12{fill:rgb(106,61,154)} -.Paired .q10-12{fill:rgb(255,255,153)} -.Paired .q11-12{fill:rgb(177,89,40)} -.Pastel1 .q0-3{fill:rgb(251,180,174)} -.Pastel1 .q1-3{fill:rgb(179,205,227)} -.Pastel1 .q2-3{fill:rgb(204,235,197)} -.Pastel1 .q0-4{fill:rgb(251,180,174)} -.Pastel1 .q1-4{fill:rgb(179,205,227)} -.Pastel1 .q2-4{fill:rgb(204,235,197)} -.Pastel1 .q3-4{fill:rgb(222,203,228)} -.Pastel1 .q0-5{fill:rgb(251,180,174)} -.Pastel1 .q1-5{fill:rgb(179,205,227)} -.Pastel1 .q2-5{fill:rgb(204,235,197)} -.Pastel1 .q3-5{fill:rgb(222,203,228)} -.Pastel1 .q4-5{fill:rgb(254,217,166)} -.Pastel1 .q0-6{fill:rgb(251,180,174)} -.Pastel1 .q1-6{fill:rgb(179,205,227)} -.Pastel1 .q2-6{fill:rgb(204,235,197)} -.Pastel1 .q3-6{fill:rgb(222,203,228)} -.Pastel1 .q4-6{fill:rgb(254,217,166)} -.Pastel1 .q5-6{fill:rgb(255,255,204)} -.Pastel1 .q0-7{fill:rgb(251,180,174)} -.Pastel1 .q1-7{fill:rgb(179,205,227)} -.Pastel1 .q2-7{fill:rgb(204,235,197)} -.Pastel1 .q3-7{fill:rgb(222,203,228)} -.Pastel1 .q4-7{fill:rgb(254,217,166)} -.Pastel1 .q5-7{fill:rgb(255,255,204)} -.Pastel1 .q6-7{fill:rgb(229,216,189)} -.Pastel1 .q0-8{fill:rgb(251,180,174)} -.Pastel1 .q1-8{fill:rgb(179,205,227)} -.Pastel1 .q2-8{fill:rgb(204,235,197)} -.Pastel1 .q3-8{fill:rgb(222,203,228)} -.Pastel1 .q4-8{fill:rgb(254,217,166)} -.Pastel1 .q5-8{fill:rgb(255,255,204)} -.Pastel1 .q6-8{fill:rgb(229,216,189)} -.Pastel1 .q7-8{fill:rgb(253,218,236)} -.Pastel1 .q0-9{fill:rgb(251,180,174)} -.Pastel1 .q1-9{fill:rgb(179,205,227)} -.Pastel1 .q2-9{fill:rgb(204,235,197)} -.Pastel1 .q3-9{fill:rgb(222,203,228)} -.Pastel1 .q4-9{fill:rgb(254,217,166)} -.Pastel1 .q5-9{fill:rgb(255,255,204)} -.Pastel1 .q6-9{fill:rgb(229,216,189)} -.Pastel1 .q7-9{fill:rgb(253,218,236)} -.Pastel1 .q8-9{fill:rgb(242,242,242)} -.Pastel2 .q0-3{fill:rgb(179,226,205)} -.Pastel2 .q1-3{fill:rgb(253,205,172)} -.Pastel2 .q2-3{fill:rgb(203,213,232)} -.Pastel2 .q0-4{fill:rgb(179,226,205)} -.Pastel2 .q1-4{fill:rgb(253,205,172)} -.Pastel2 .q2-4{fill:rgb(203,213,232)} -.Pastel2 .q3-4{fill:rgb(244,202,228)} -.Pastel2 .q0-5{fill:rgb(179,226,205)} -.Pastel2 .q1-5{fill:rgb(253,205,172)} -.Pastel2 .q2-5{fill:rgb(203,213,232)} -.Pastel2 .q3-5{fill:rgb(244,202,228)} -.Pastel2 .q4-5{fill:rgb(230,245,201)} -.Pastel2 .q0-6{fill:rgb(179,226,205)} -.Pastel2 .q1-6{fill:rgb(253,205,172)} -.Pastel2 .q2-6{fill:rgb(203,213,232)} -.Pastel2 .q3-6{fill:rgb(244,202,228)} -.Pastel2 .q4-6{fill:rgb(230,245,201)} -.Pastel2 .q5-6{fill:rgb(255,242,174)} -.Pastel2 .q0-7{fill:rgb(179,226,205)} -.Pastel2 .q1-7{fill:rgb(253,205,172)} -.Pastel2 .q2-7{fill:rgb(203,213,232)} -.Pastel2 .q3-7{fill:rgb(244,202,228)} -.Pastel2 .q4-7{fill:rgb(230,245,201)} -.Pastel2 .q5-7{fill:rgb(255,242,174)} -.Pastel2 .q6-7{fill:rgb(241,226,204)} -.Pastel2 .q0-8{fill:rgb(179,226,205)} -.Pastel2 .q1-8{fill:rgb(253,205,172)} -.Pastel2 .q2-8{fill:rgb(203,213,232)} -.Pastel2 .q3-8{fill:rgb(244,202,228)} -.Pastel2 .q4-8{fill:rgb(230,245,201)} -.Pastel2 .q5-8{fill:rgb(255,242,174)} -.Pastel2 .q6-8{fill:rgb(241,226,204)} -.Pastel2 .q7-8{fill:rgb(204,204,204)} -.Set1 .q0-3{fill:rgb(228,26,28)} -.Set1 .q1-3{fill:rgb(55,126,184)} -.Set1 .q2-3{fill:rgb(77,175,74)} -.Set1 .q0-4{fill:rgb(228,26,28)} -.Set1 .q1-4{fill:rgb(55,126,184)} -.Set1 .q2-4{fill:rgb(77,175,74)} -.Set1 .q3-4{fill:rgb(152,78,163)} -.Set1 .q0-5{fill:rgb(228,26,28)} -.Set1 .q1-5{fill:rgb(55,126,184)} -.Set1 .q2-5{fill:rgb(77,175,74)} -.Set1 .q3-5{fill:rgb(152,78,163)} -.Set1 .q4-5{fill:rgb(255,127,0)} -.Set1 .q0-6{fill:rgb(228,26,28)} -.Set1 .q1-6{fill:rgb(55,126,184)} -.Set1 .q2-6{fill:rgb(77,175,74)} -.Set1 .q3-6{fill:rgb(152,78,163)} -.Set1 .q4-6{fill:rgb(255,127,0)} -.Set1 .q5-6{fill:rgb(255,255,51)} -.Set1 .q0-7{fill:rgb(228,26,28)} -.Set1 .q1-7{fill:rgb(55,126,184)} -.Set1 .q2-7{fill:rgb(77,175,74)} -.Set1 .q3-7{fill:rgb(152,78,163)} -.Set1 .q4-7{fill:rgb(255,127,0)} -.Set1 .q5-7{fill:rgb(255,255,51)} -.Set1 .q6-7{fill:rgb(166,86,40)} -.Set1 .q0-8{fill:rgb(228,26,28)} -.Set1 .q1-8{fill:rgb(55,126,184)} -.Set1 .q2-8{fill:rgb(77,175,74)} -.Set1 .q3-8{fill:rgb(152,78,163)} -.Set1 .q4-8{fill:rgb(255,127,0)} -.Set1 .q5-8{fill:rgb(255,255,51)} -.Set1 .q6-8{fill:rgb(166,86,40)} -.Set1 .q7-8{fill:rgb(247,129,191)} -.Set1 .q0-9{fill:rgb(228,26,28)} -.Set1 .q1-9{fill:rgb(55,126,184)} -.Set1 .q2-9{fill:rgb(77,175,74)} -.Set1 .q3-9{fill:rgb(152,78,163)} -.Set1 .q4-9{fill:rgb(255,127,0)} -.Set1 .q5-9{fill:rgb(255,255,51)} -.Set1 .q6-9{fill:rgb(166,86,40)} -.Set1 .q7-9{fill:rgb(247,129,191)} -.Set1 .q8-9{fill:rgb(153,153,153)} -.Set2 .q0-3{fill:rgb(102,194,165)} -.Set2 .q1-3{fill:rgb(252,141,98)} -.Set2 .q2-3{fill:rgb(141,160,203)} -.Set2 .q0-4{fill:rgb(102,194,165)} -.Set2 .q1-4{fill:rgb(252,141,98)} -.Set2 .q2-4{fill:rgb(141,160,203)} -.Set2 .q3-4{fill:rgb(231,138,195)} -.Set2 .q0-5{fill:rgb(102,194,165)} -.Set2 .q1-5{fill:rgb(252,141,98)} -.Set2 .q2-5{fill:rgb(141,160,203)} -.Set2 .q3-5{fill:rgb(231,138,195)} -.Set2 .q4-5{fill:rgb(166,216,84)} -.Set2 .q0-6{fill:rgb(102,194,165)} -.Set2 .q1-6{fill:rgb(252,141,98)} -.Set2 .q2-6{fill:rgb(141,160,203)} -.Set2 .q3-6{fill:rgb(231,138,195)} -.Set2 .q4-6{fill:rgb(166,216,84)} -.Set2 .q5-6{fill:rgb(255,217,47)} -.Set2 .q0-7{fill:rgb(102,194,165)} -.Set2 .q1-7{fill:rgb(252,141,98)} -.Set2 .q2-7{fill:rgb(141,160,203)} -.Set2 .q3-7{fill:rgb(231,138,195)} -.Set2 .q4-7{fill:rgb(166,216,84)} -.Set2 .q5-7{fill:rgb(255,217,47)} -.Set2 .q6-7{fill:rgb(229,196,148)} -.Set2 .q0-8{fill:rgb(102,194,165)} -.Set2 .q1-8{fill:rgb(252,141,98)} -.Set2 .q2-8{fill:rgb(141,160,203)} -.Set2 .q3-8{fill:rgb(231,138,195)} -.Set2 .q4-8{fill:rgb(166,216,84)} -.Set2 .q5-8{fill:rgb(255,217,47)} -.Set2 .q6-8{fill:rgb(229,196,148)} -.Set2 .q7-8{fill:rgb(179,179,179)} -.Set3 .q0-3{fill:rgb(141,211,199)} -.Set3 .q1-3{fill:rgb(255,255,179)} -.Set3 .q2-3{fill:rgb(190,186,218)} -.Set3 .q0-4{fill:rgb(141,211,199)} -.Set3 .q1-4{fill:rgb(255,255,179)} -.Set3 .q2-4{fill:rgb(190,186,218)} -.Set3 .q3-4{fill:rgb(251,128,114)} -.Set3 .q0-5{fill:rgb(141,211,199)} -.Set3 .q1-5{fill:rgb(255,255,179)} -.Set3 .q2-5{fill:rgb(190,186,218)} -.Set3 .q3-5{fill:rgb(251,128,114)} -.Set3 .q4-5{fill:rgb(128,177,211)} -.Set3 .q0-6{fill:rgb(141,211,199)} -.Set3 .q1-6{fill:rgb(255,255,179)} -.Set3 .q2-6{fill:rgb(190,186,218)} -.Set3 .q3-6{fill:rgb(251,128,114)} -.Set3 .q4-6{fill:rgb(128,177,211)} -.Set3 .q5-6{fill:rgb(253,180,98)} -.Set3 .q0-7{fill:rgb(141,211,199)} -.Set3 .q1-7{fill:rgb(255,255,179)} -.Set3 .q2-7{fill:rgb(190,186,218)} -.Set3 .q3-7{fill:rgb(251,128,114)} -.Set3 .q4-7{fill:rgb(128,177,211)} -.Set3 .q5-7{fill:rgb(253,180,98)} -.Set3 .q6-7{fill:rgb(179,222,105)} -.Set3 .q0-8{fill:rgb(141,211,199)} -.Set3 .q1-8{fill:rgb(255,255,179)} -.Set3 .q2-8{fill:rgb(190,186,218)} -.Set3 .q3-8{fill:rgb(251,128,114)} -.Set3 .q4-8{fill:rgb(128,177,211)} -.Set3 .q5-8{fill:rgb(253,180,98)} -.Set3 .q6-8{fill:rgb(179,222,105)} -.Set3 .q7-8{fill:rgb(252,205,229)} -.Set3 .q0-9{fill:rgb(141,211,199)} -.Set3 .q1-9{fill:rgb(255,255,179)} -.Set3 .q2-9{fill:rgb(190,186,218)} -.Set3 .q3-9{fill:rgb(251,128,114)} -.Set3 .q4-9{fill:rgb(128,177,211)} -.Set3 .q5-9{fill:rgb(253,180,98)} -.Set3 .q6-9{fill:rgb(179,222,105)} -.Set3 .q7-9{fill:rgb(252,205,229)} -.Set3 .q8-9{fill:rgb(217,217,217)} -.Set3 .q0-10{fill:rgb(141,211,199)} -.Set3 .q1-10{fill:rgb(255,255,179)} -.Set3 .q2-10{fill:rgb(190,186,218)} -.Set3 .q3-10{fill:rgb(251,128,114)} -.Set3 .q4-10{fill:rgb(128,177,211)} -.Set3 .q5-10{fill:rgb(253,180,98)} -.Set3 .q6-10{fill:rgb(179,222,105)} -.Set3 .q7-10{fill:rgb(252,205,229)} -.Set3 .q8-10{fill:rgb(217,217,217)} -.Set3 .q9-10{fill:rgb(188,128,189)} -.Set3 .q0-11{fill:rgb(141,211,199)} -.Set3 .q1-11{fill:rgb(255,255,179)} -.Set3 .q2-11{fill:rgb(190,186,218)} -.Set3 .q3-11{fill:rgb(251,128,114)} -.Set3 .q4-11{fill:rgb(128,177,211)} -.Set3 .q5-11{fill:rgb(253,180,98)} -.Set3 .q6-11{fill:rgb(179,222,105)} -.Set3 .q7-11{fill:rgb(252,205,229)} -.Set3 .q8-11{fill:rgb(217,217,217)} -.Set3 .q9-11{fill:rgb(188,128,189)} -.Set3 .q10-11{fill:rgb(204,235,197)} -.Set3 .q0-12{fill:rgb(141,211,199)} -.Set3 .q1-12{fill:rgb(255,255,179)} -.Set3 .q2-12{fill:rgb(190,186,218)} -.Set3 .q3-12{fill:rgb(251,128,114)} -.Set3 .q4-12{fill:rgb(128,177,211)} -.Set3 .q5-12{fill:rgb(253,180,98)} -.Set3 .q6-12{fill:rgb(179,222,105)} -.Set3 .q7-12{fill:rgb(252,205,229)} -.Set3 .q8-12{fill:rgb(217,217,217)} -.Set3 .q9-12{fill:rgb(188,128,189)} -.Set3 .q10-12{fill:rgb(204,235,197)} -.Set3 .q11-12{fill:rgb(255,237,111)} diff --git a/lib/colorbrewer/colorbrewer.js b/lib/colorbrewer/colorbrewer.js deleted file mode 100644 index 2295527b9d7933..00000000000000 --- a/lib/colorbrewer/colorbrewer.js +++ /dev/null @@ -1,302 +0,0 @@ -// This product includes color specifications and designs developed by Cynthia Brewer (http://colorbrewer.org/). -var colorbrewer = {YlGn: { -3: ["#f7fcb9","#addd8e","#31a354"], -4: ["#ffffcc","#c2e699","#78c679","#238443"], -5: ["#ffffcc","#c2e699","#78c679","#31a354","#006837"], -6: ["#ffffcc","#d9f0a3","#addd8e","#78c679","#31a354","#006837"], -7: ["#ffffcc","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"], -8: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"], -9: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"] -},YlGnBu: { -3: ["#edf8b1","#7fcdbb","#2c7fb8"], -4: ["#ffffcc","#a1dab4","#41b6c4","#225ea8"], -5: ["#ffffcc","#a1dab4","#41b6c4","#2c7fb8","#253494"], -6: ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#2c7fb8","#253494"], -7: ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"], -8: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"], -9: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"] -},GnBu: { -3: ["#e0f3db","#a8ddb5","#43a2ca"], -4: ["#f0f9e8","#bae4bc","#7bccc4","#2b8cbe"], -5: ["#f0f9e8","#bae4bc","#7bccc4","#43a2ca","#0868ac"], -6: ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#43a2ca","#0868ac"], -7: ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"], -8: ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"], -9: ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"] -},BuGn: { -3: ["#e5f5f9","#99d8c9","#2ca25f"], -4: ["#edf8fb","#b2e2e2","#66c2a4","#238b45"], -5: ["#edf8fb","#b2e2e2","#66c2a4","#2ca25f","#006d2c"], -6: ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#2ca25f","#006d2c"], -7: ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"], -8: ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"], -9: ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"] -},PuBuGn: { -3: ["#ece2f0","#a6bddb","#1c9099"], -4: ["#f6eff7","#bdc9e1","#67a9cf","#02818a"], -5: ["#f6eff7","#bdc9e1","#67a9cf","#1c9099","#016c59"], -6: ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#1c9099","#016c59"], -7: ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"], -8: ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"], -9: ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"] -},PuBu: { -3: ["#ece7f2","#a6bddb","#2b8cbe"], -4: ["#f1eef6","#bdc9e1","#74a9cf","#0570b0"], -5: ["#f1eef6","#bdc9e1","#74a9cf","#2b8cbe","#045a8d"], -6: ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#2b8cbe","#045a8d"], -7: ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"], -8: ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"], -9: ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"] -},BuPu: { -3: ["#e0ecf4","#9ebcda","#8856a7"], -4: ["#edf8fb","#b3cde3","#8c96c6","#88419d"], -5: ["#edf8fb","#b3cde3","#8c96c6","#8856a7","#810f7c"], -6: ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8856a7","#810f7c"], -7: ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"], -8: ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"], -9: ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"] -},RdPu: { -3: ["#fde0dd","#fa9fb5","#c51b8a"], -4: ["#feebe2","#fbb4b9","#f768a1","#ae017e"], -5: ["#feebe2","#fbb4b9","#f768a1","#c51b8a","#7a0177"], -6: ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#c51b8a","#7a0177"], -7: ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"], -8: ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"], -9: ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"] -},PuRd: { -3: ["#e7e1ef","#c994c7","#dd1c77"], -4: ["#f1eef6","#d7b5d8","#df65b0","#ce1256"], -5: ["#f1eef6","#d7b5d8","#df65b0","#dd1c77","#980043"], -6: ["#f1eef6","#d4b9da","#c994c7","#df65b0","#dd1c77","#980043"], -7: ["#f1eef6","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"], -8: ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"], -9: ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"] -},OrRd: { -3: ["#fee8c8","#fdbb84","#e34a33"], -4: ["#fef0d9","#fdcc8a","#fc8d59","#d7301f"], -5: ["#fef0d9","#fdcc8a","#fc8d59","#e34a33","#b30000"], -6: ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#e34a33","#b30000"], -7: ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"], -8: ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"], -9: ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"] -},YlOrRd: { -3: ["#ffeda0","#feb24c","#f03b20"], -4: ["#ffffb2","#fecc5c","#fd8d3c","#e31a1c"], -5: ["#ffffb2","#fecc5c","#fd8d3c","#f03b20","#bd0026"], -6: ["#ffffb2","#fed976","#feb24c","#fd8d3c","#f03b20","#bd0026"], -7: ["#ffffb2","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"], -8: ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"], -9: ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"] -},YlOrBr: { -3: ["#fff7bc","#fec44f","#d95f0e"], -4: ["#ffffd4","#fed98e","#fe9929","#cc4c02"], -5: ["#ffffd4","#fed98e","#fe9929","#d95f0e","#993404"], -6: ["#ffffd4","#fee391","#fec44f","#fe9929","#d95f0e","#993404"], -7: ["#ffffd4","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"], -8: ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"], -9: ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"] -},Purples: { -3: ["#efedf5","#bcbddc","#756bb1"], -4: ["#f2f0f7","#cbc9e2","#9e9ac8","#6a51a3"], -5: ["#f2f0f7","#cbc9e2","#9e9ac8","#756bb1","#54278f"], -6: ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#756bb1","#54278f"], -7: ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"], -8: ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"], -9: ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"] -},Blues: { -3: ["#deebf7","#9ecae1","#3182bd"], -4: ["#eff3ff","#bdd7e7","#6baed6","#2171b5"], -5: ["#eff3ff","#bdd7e7","#6baed6","#3182bd","#08519c"], -6: ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#3182bd","#08519c"], -7: ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"], -8: ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"], -9: ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"] -},Greens: { -3: ["#e5f5e0","#a1d99b","#31a354"], -4: ["#edf8e9","#bae4b3","#74c476","#238b45"], -5: ["#edf8e9","#bae4b3","#74c476","#31a354","#006d2c"], -6: ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#31a354","#006d2c"], -7: ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"], -8: ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"], -9: ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"] -},Oranges: { -3: ["#fee6ce","#fdae6b","#e6550d"], -4: ["#feedde","#fdbe85","#fd8d3c","#d94701"], -5: ["#feedde","#fdbe85","#fd8d3c","#e6550d","#a63603"], -6: ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#e6550d","#a63603"], -7: ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"], -8: ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"], -9: ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"] -},Reds: { -3: ["#fee0d2","#fc9272","#de2d26"], -4: ["#fee5d9","#fcae91","#fb6a4a","#cb181d"], -5: ["#fee5d9","#fcae91","#fb6a4a","#de2d26","#a50f15"], -6: ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#de2d26","#a50f15"], -7: ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"], -8: ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"], -9: ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"] -},Greys: { -3: ["#f0f0f0","#bdbdbd","#636363"], -4: ["#f7f7f7","#cccccc","#969696","#525252"], -5: ["#f7f7f7","#cccccc","#969696","#636363","#252525"], -6: ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#636363","#252525"], -7: ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"], -8: ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"], -9: ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"] -},PuOr: { -3: ["#f1a340","#f7f7f7","#998ec3"], -4: ["#e66101","#fdb863","#b2abd2","#5e3c99"], -5: ["#e66101","#fdb863","#f7f7f7","#b2abd2","#5e3c99"], -6: ["#b35806","#f1a340","#fee0b6","#d8daeb","#998ec3","#542788"], -7: ["#b35806","#f1a340","#fee0b6","#f7f7f7","#d8daeb","#998ec3","#542788"], -8: ["#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788"], -9: ["#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788"], -10: ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"], -11: ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"] -},BrBG: { -3: ["#d8b365","#f5f5f5","#5ab4ac"], -4: ["#a6611a","#dfc27d","#80cdc1","#018571"], -5: ["#a6611a","#dfc27d","#f5f5f5","#80cdc1","#018571"], -6: ["#8c510a","#d8b365","#f6e8c3","#c7eae5","#5ab4ac","#01665e"], -7: ["#8c510a","#d8b365","#f6e8c3","#f5f5f5","#c7eae5","#5ab4ac","#01665e"], -8: ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e"], -9: ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e"], -10: ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"], -11: ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"] -},PRGn: { -3: ["#af8dc3","#f7f7f7","#7fbf7b"], -4: ["#7b3294","#c2a5cf","#a6dba0","#008837"], -5: ["#7b3294","#c2a5cf","#f7f7f7","#a6dba0","#008837"], -6: ["#762a83","#af8dc3","#e7d4e8","#d9f0d3","#7fbf7b","#1b7837"], -7: ["#762a83","#af8dc3","#e7d4e8","#f7f7f7","#d9f0d3","#7fbf7b","#1b7837"], -8: ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837"], -9: ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837"], -10: ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"], -11: ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"] -},PiYG: { -3: ["#e9a3c9","#f7f7f7","#a1d76a"], -4: ["#d01c8b","#f1b6da","#b8e186","#4dac26"], -5: ["#d01c8b","#f1b6da","#f7f7f7","#b8e186","#4dac26"], -6: ["#c51b7d","#e9a3c9","#fde0ef","#e6f5d0","#a1d76a","#4d9221"], -7: ["#c51b7d","#e9a3c9","#fde0ef","#f7f7f7","#e6f5d0","#a1d76a","#4d9221"], -8: ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221"], -9: ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221"], -10: ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"], -11: ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"] -},RdBu: { -3: ["#ef8a62","#f7f7f7","#67a9cf"], -4: ["#ca0020","#f4a582","#92c5de","#0571b0"], -5: ["#ca0020","#f4a582","#f7f7f7","#92c5de","#0571b0"], -6: ["#b2182b","#ef8a62","#fddbc7","#d1e5f0","#67a9cf","#2166ac"], -7: ["#b2182b","#ef8a62","#fddbc7","#f7f7f7","#d1e5f0","#67a9cf","#2166ac"], -8: ["#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac"], -9: ["#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac"], -10: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"], -11: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"] -},RdGy: { -3: ["#ef8a62","#ffffff","#999999"], -4: ["#ca0020","#f4a582","#bababa","#404040"], -5: ["#ca0020","#f4a582","#ffffff","#bababa","#404040"], -6: ["#b2182b","#ef8a62","#fddbc7","#e0e0e0","#999999","#4d4d4d"], -7: ["#b2182b","#ef8a62","#fddbc7","#ffffff","#e0e0e0","#999999","#4d4d4d"], -8: ["#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d"], -9: ["#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d"], -10: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"], -11: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"] -},RdYlBu: { -3: ["#fc8d59","#ffffbf","#91bfdb"], -4: ["#d7191c","#fdae61","#abd9e9","#2c7bb6"], -5: ["#d7191c","#fdae61","#ffffbf","#abd9e9","#2c7bb6"], -6: ["#d73027","#fc8d59","#fee090","#e0f3f8","#91bfdb","#4575b4"], -7: ["#d73027","#fc8d59","#fee090","#ffffbf","#e0f3f8","#91bfdb","#4575b4"], -8: ["#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4"], -9: ["#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4"], -10: ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"], -11: ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"] -},Spectral: { -3: ["#fc8d59","#ffffbf","#99d594"], -4: ["#d7191c","#fdae61","#abdda4","#2b83ba"], -5: ["#d7191c","#fdae61","#ffffbf","#abdda4","#2b83ba"], -6: ["#d53e4f","#fc8d59","#fee08b","#e6f598","#99d594","#3288bd"], -7: ["#d53e4f","#fc8d59","#fee08b","#ffffbf","#e6f598","#99d594","#3288bd"], -8: ["#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd"], -9: ["#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd"], -10: ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"], -11: ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"] -},RdYlGn: { -3: ["#fc8d59","#ffffbf","#91cf60"], -4: ["#d7191c","#fdae61","#a6d96a","#1a9641"], -5: ["#d7191c","#fdae61","#ffffbf","#a6d96a","#1a9641"], -6: ["#d73027","#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"], -7: ["#d73027","#fc8d59","#fee08b","#ffffbf","#d9ef8b","#91cf60","#1a9850"], -8: ["#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850"], -9: ["#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850"], -10: ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"], -11: ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"] -},Accent: { -3: ["#7fc97f","#beaed4","#fdc086"], -4: ["#7fc97f","#beaed4","#fdc086","#ffff99"], -5: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0"], -6: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f"], -7: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17"], -8: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"] -},Dark2: { -3: ["#1b9e77","#d95f02","#7570b3"], -4: ["#1b9e77","#d95f02","#7570b3","#e7298a"], -5: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e"], -6: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02"], -7: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d"], -8: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"] -},Paired: { -3: ["#a6cee3","#1f78b4","#b2df8a"], -4: ["#a6cee3","#1f78b4","#b2df8a","#33a02c"], -5: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99"], -6: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c"], -7: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f"], -8: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00"], -9: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6"], -10: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a"], -11: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99"], -12: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"] -},Pastel1: { -3: ["#fbb4ae","#b3cde3","#ccebc5"], -4: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4"], -5: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6"], -6: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc"], -7: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd"], -8: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec"], -9: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"] -},Pastel2: { -3: ["#b3e2cd","#fdcdac","#cbd5e8"], -4: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4"], -5: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9"], -6: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae"], -7: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc"], -8: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"] -},Set1: { -3: ["#e41a1c","#377eb8","#4daf4a"], -4: ["#e41a1c","#377eb8","#4daf4a","#984ea3"], -5: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00"], -6: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33"], -7: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628"], -8: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf"], -9: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"] -},Set2: { -3: ["#66c2a5","#fc8d62","#8da0cb"], -4: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3"], -5: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854"], -6: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f"], -7: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494"], -8: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"] -},Set3: { -3: ["#8dd3c7","#ffffb3","#bebada"], -4: ["#8dd3c7","#ffffb3","#bebada","#fb8072"], -5: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3"], -6: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462"], -7: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69"], -8: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5"], -9: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9"], -10: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd"], -11: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5"], -12: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"] -}}; diff --git a/lib/geographiclib/LICENSE b/lib/geographiclib/LICENSE deleted file mode 100644 index 692304ce3eec01..00000000000000 --- a/lib/geographiclib/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -This license applies to GeographicLib, versions 1.12 and later. - -Copyright (c) 2008-2012, Charles Karney - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, copy, -modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/lib/jit/LICENSE b/lib/jit/LICENSE deleted file mode 100644 index e55999e5a48736..00000000000000 --- a/lib/jit/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2010, Nicolas Garcia Belmonte -All rights reserved - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the organization nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY NICOLAS GARCIA BELMONTE ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL NICOLAS GARCIA BELMONTE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/penner/LICENSE b/lib/penner/LICENSE deleted file mode 100644 index 84296855b4ba0a..00000000000000 --- a/lib/penner/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -TERMS OF USE - EASING EQUATIONS - -Open source under the BSD License. - -Copyright 2001 Robert Penner -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -- Neither the name of the author nor the names of contributors may be used to - endorse or promote products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/polymaps/LICENSE b/lib/polymaps/LICENSE deleted file mode 100644 index df48fc514fae24..00000000000000 --- a/lib/polymaps/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2010, SimpleGeo and Stamen Design -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of SimpleGeo nor the names of its contributors may be used - to endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL SIMPLEGEO BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/lib/protovis/LICENSE b/lib/protovis/LICENSE deleted file mode 100644 index 4c6e405592489a..00000000000000 --- a/lib/protovis/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2010, Stanford Visualization Group -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of Stanford University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/science/LICENSE b/lib/science/LICENSE deleted file mode 100644 index a59d17ee6dff87..00000000000000 --- a/lib/science/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2011, Jason Davies -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * The name Jason Davies may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL JASON DAVIES BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/science/science.js b/lib/science/science.js deleted file mode 100644 index 2f5556a22a38bc..00000000000000 --- a/lib/science/science.js +++ /dev/null @@ -1,225 +0,0 @@ -(function(){science = {version: "1.7.0"}; // semver -science.ascending = function(a, b) { - return a - b; -}; -// Euler's constant. -science.EULER = .5772156649015329; -// Compute exp(x) - 1 accurately for small x. -science.expm1 = function(x) { - return (x < 1e-5 && x > -1e-5) ? x + .5 * x * x : Math.exp(x) - 1; -}; -science.functor = function(v) { - return typeof v === "function" ? v : function() { return v; }; -}; -// Based on: -// http://www.johndcook.com/blog/2010/06/02/whats-so-hard-about-finding-a-hypotenuse/ -science.hypot = function(x, y) { - x = Math.abs(x); - y = Math.abs(y); - var max, - min; - if (x > y) { max = x; min = y; } - else { max = y; min = x; } - var r = min / max; - return max * Math.sqrt(1 + r * r); -}; -science.quadratic = function() { - var complex = false; - - function quadratic(a, b, c) { - var d = b * b - 4 * a * c; - if (d > 0) { - d = Math.sqrt(d) / (2 * a); - return complex - ? [{r: -b - d, i: 0}, {r: -b + d, i: 0}] - : [-b - d, -b + d]; - } else if (d === 0) { - d = -b / (2 * a); - return complex ? [{r: d, i: 0}] : [d]; - } else { - if (complex) { - d = Math.sqrt(-d) / (2 * a); - return [ - {r: -b, i: -d}, - {r: -b, i: d} - ]; - } - return []; - } - } - - quadratic.complex = function(x) { - if (!arguments.length) return complex; - complex = x; - return quadratic; - }; - - return quadratic; -}; -// Constructs a multi-dimensional array filled with zeroes. -science.zeroes = function(n) { - var i = -1, - a = []; - if (arguments.length === 1) - while (++i < n) - a[i] = 0; - else - while (++i < n) - a[i] = science.zeroes.apply( - this, Array.prototype.slice.call(arguments, 1)); - return a; -}; -science.vector = {}; -science.vector.cross = function(a, b) { - // TODO how to handle non-3D vectors? - // TODO handle 7D vectors? - return [ - a[1] * b[2] - a[2] * b[1], - a[2] * b[0] - a[0] * b[2], - a[0] * b[1] - a[1] * b[0] - ]; -}; -science.vector.dot = function(a, b) { - var s = 0, - i = -1, - n = Math.min(a.length, b.length); - while (++i < n) s += a[i] * b[i]; - return s; -}; -science.vector.length = function(p) { - return Math.sqrt(science.vector.dot(p, p)); -}; -science.vector.normalize = function(p) { - var length = science.vector.length(p); - return p.map(function(d) { return d / length; }); -}; -// 4x4 matrix determinant. -science.vector.determinant = function(matrix) { - var m = matrix[0].concat(matrix[1]).concat(matrix[2]).concat(matrix[3]); - return ( - m[12] * m[9] * m[6] * m[3] - m[8] * m[13] * m[6] * m[3] - - m[12] * m[5] * m[10] * m[3] + m[4] * m[13] * m[10] * m[3] + - m[8] * m[5] * m[14] * m[3] - m[4] * m[9] * m[14] * m[3] - - m[12] * m[9] * m[2] * m[7] + m[8] * m[13] * m[2] * m[7] + - m[12] * m[1] * m[10] * m[7] - m[0] * m[13] * m[10] * m[7] - - m[8] * m[1] * m[14] * m[7] + m[0] * m[9] * m[14] * m[7] + - m[12] * m[5] * m[2] * m[11] - m[4] * m[13] * m[2] * m[11] - - m[12] * m[1] * m[6] * m[11] + m[0] * m[13] * m[6] * m[11] + - m[4] * m[1] * m[14] * m[11] - m[0] * m[5] * m[14] * m[11] - - m[8] * m[5] * m[2] * m[15] + m[4] * m[9] * m[2] * m[15] + - m[8] * m[1] * m[6] * m[15] - m[0] * m[9] * m[6] * m[15] - - m[4] * m[1] * m[10] * m[15] + m[0] * m[5] * m[10] * m[15]); -}; -// Performs in-place Gauss-Jordan elimination. -// -// Based on Jarno Elonen's Python version (public domain): -// http://elonen.iki.fi/code/misc-notes/python-gaussj/index.html -science.vector.gaussjordan = function(m, eps) { - if (!eps) eps = 1e-10; - - var h = m.length, - w = m[0].length, - y = -1, - y2, - x; - - while (++y < h) { - var maxrow = y; - - // Find max pivot. - y2 = y; while (++y2 < h) { - if (Math.abs(m[y2][y]) > Math.abs(m[maxrow][y])) - maxrow = y2; - } - - // Swap. - var tmp = m[y]; - m[y] = m[maxrow]; - m[maxrow] = tmp; - - // Singular? - if (Math.abs(m[y][y]) <= eps) return false; - - // Eliminate column y. - y2 = y; while (++y2 < h) { - var c = m[y2][y] / m[y][y]; - x = y - 1; while (++x < w) { - m[y2][x] -= m[y][x] * c; - } - } - } - - // Backsubstitute. - y = h; while (--y >= 0) { - var c = m[y][y]; - y2 = -1; while (++y2 < y) { - x = w; while (--x >= y) { - m[y2][x] -= m[y][x] * m[y2][y] / c; - } - } - m[y][y] /= c; - // Normalize row y. - x = h - 1; while (++x < w) { - m[y][x] /= c; - } - } - return true; -}; -// Find matrix inverse using Gauss-Jordan. -science.vector.inverse = function(m) { - var n = m.length - i = -1; - - // Check if the matrix is square. - if (n !== m[0].length) return; - - // Augment with identity matrix I to get AI. - m = m.map(function(row, i) { - var identity = new Array(n), - j = -1; - while (++j < n) identity[j] = i === j ? 1 : 0; - return row.concat(identity); - }); - - // Compute IA^-1. - science.vector.gaussjordan(m); - - // Remove identity matrix I to get A^-1. - while (++i < n) { - m[i] = m[i].slice(n); - } - - return m; -}; -science.vector.multiply = function(a, b) { - var m = a.length, - n = b[0].length, - p = b.length, - i = -1, - j, - k; - if (p !== a[0].length) throw {"error": "columns(a) != rows(b); " + a[0].length + " != " + p}; - var ab = new Array(m); - while (++i < m) { - ab[i] = new Array(n); - j = -1; while(++j < n) { - var s = 0; - k = -1; while (++k < p) s += a[i][k] * b[k][j]; - ab[i][j] = s; - } - } - return ab; -}; -science.vector.transpose = function(a) { - var m = a.length, - n = a[0].length, - i = -1, - j, - b = new Array(n); - while (++i < n) { - b[i] = new Array(m); - j = -1; while (++j < m) b[i][j] = a[j][i]; - } - return b; -}; -})() \ No newline at end of file diff --git a/lib/science/science.lin.js b/lib/science/science.lin.js deleted file mode 100644 index cbdc2ac636f0ef..00000000000000 --- a/lib/science/science.lin.js +++ /dev/null @@ -1,27 +0,0 @@ -(function(){science.lin = {}; -/** - * Solves tridiagonal systems of linear equations. - * - * Source: http://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm - * - * @param {number[]} a - * @param {number[]} b - * @param {number[]} c - * @param {number[]} d - * @param {number[]} x - * @param {number} n - */ -science.lin.tridag = function(a, b, c, d, x, n) { - var i, - m; - for (i = 1; i < n; i++) { - m = a[i] / b[i - 1]; - b[i] -= m * c[i - 1]; - d[i] -= m * d[i - 1]; - } - x[n - 1] = d[n - 1] / b[n - 1]; - for (i = n - 2; i >= 0; i--) { - x[i] = (d[i] - c[i] * x[i + 1]) / b[i]; - } -}; -})() \ No newline at end of file diff --git a/lib/science/science.lin.min.js b/lib/science/science.lin.min.js deleted file mode 100644 index a470da465fb5c1..00000000000000 --- a/lib/science/science.lin.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(){science.lin={},science.lin.tridag=function(a,b,c,d,e,f){var g,h;for(g=1;g=0;g--)e[g]=(d[g]-c[g]*e[g+1])/b[g]}})() \ No newline at end of file diff --git a/lib/science/science.min.js b/lib/science/science.min.js deleted file mode 100644 index 41cf0ebbcb4ea7..00000000000000 --- a/lib/science/science.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(){science={version:"1.7.0"},science.ascending=function(a,b){return a-b},science.EULER=.5772156649015329,science.expm1=function(a){return a<1e-5&&a>-0.00001?a+.5*a*a:Math.exp(a)-1},science.functor=function(a){return typeof a=="function"?a:function(){return a}},science.hypot=function(a,b){a=Math.abs(a),b=Math.abs(b);var c,d;a>b?(c=a,d=b):(c=b,d=a);var e=d/c;return c*Math.sqrt(1+e*e)},science.quadratic=function(){function b(b,c,d){var e=c*c-4*b*d;if(e>0){e=Math.sqrt(e)/(2*b);return a?[{r:-c-e,i:0},{r:-c+e,i:0}]:[-c-e,-c+e]}if(e===0){e=-c/(2*b);return a?[{r:e,i:0}]:[e]}if(a){e=Math.sqrt(-e)/(2*b);return[{r:-c,i:-e},{r:-c,i:e}]}return[]}var a=!1;b.complex=function(c){if(!arguments.length)return a;a=c;return b};return b},science.zeroes=function(a){var b=-1,c=[];if(arguments.length===1)while(++bMath.abs(a[h][e])&&(h=f);var i=a[e];a[e]=a[h],a[h]=i;if(Math.abs(a[e][e])<=b)return!1;f=e;while(++f=0){var j=a[e][e];f=-1;while(++f=e)a[f][g]-=a[e][g]*a[f][e]/j}a[e][e]/=j,g=c-1;while(++g distMatrix[i][j]) dMin[i] = j; - } - } - - // create leaves of the tree - i = -1; while (++i < n) { - clusters[i] = []; - clusters[i][0] = { - left: null, - right: null, - dist: 0, - centroid: vectors[i], - size: 1, - depth: 0 - }; - cSize[i] = 1; - } - - // Main loop - for (p = 0; p < n-1; p++) { - // find the closest pair of clusters - c1 = 0; - for (i = 0; i < n; i++) { - if (distMatrix[i][dMin[i]] < distMatrix[c1][dMin[c1]]) c1 = i; - } - c2 = dMin[c1]; - - // create node to store cluster info - c1Cluster = clusters[c1][0]; - c2Cluster = clusters[c2][0]; - - newCluster = { - left: c1Cluster, - right: c2Cluster, - dist: distMatrix[c1][c2], - centroid: calculateCentroid(c1Cluster.size, c1Cluster.centroid, - c2Cluster.size, c2Cluster.centroid), - size: c1Cluster.size + c2Cluster.size, - depth: 1 + Math.max(c1Cluster.depth, c2Cluster.depth) - }; - clusters[c1].splice(0, 0, newCluster); - cSize[c1] += cSize[c2]; - - // overwrite row c1 with respect to the linkage type - for (j = 0; j < n; j++) { - switch (linkage) { - case "single": - if (distMatrix[c1][j] > distMatrix[c2][j]) - distMatrix[j][c1] = distMatrix[c1][j] = distMatrix[c2][j]; - break; - case "complete": - if (distMatrix[c1][j] < distMatrix[c2][j]) - distMatrix[j][c1] = distMatrix[c1][j] = distMatrix[c2][j]; - break; - case "average": - distMatrix[j][c1] = distMatrix[c1][j] = (cSize[c1] * distMatrix[c1][j] + cSize[c2] * distMatrix[c2][j]) / (cSize[c1] + cSize[j]); - break; - } - } - distMatrix[c1][c1] = Infinity; - - // infinity ­out old row c2 and column c2 - for (i = 0; i < n; i++) - distMatrix[i][c2] = distMatrix[c2][i] = Infinity; - - // update dmin and replace ones that previous pointed to c2 to point to c1 - for (j = 0; j < n; j++) { - if (dMin[j] == c2) dMin[j] = c1; - if (distMatrix[c1][j] < distMatrix[c1][dMin[c1]]) dMin[c1] = j; - } - - // keep track of the last added cluster - root = newCluster; - } - - return root; - } - - hcluster.distance = function(x) { - if (!arguments.length) return distance; - distance = x; - return hcluster; - }; - - return hcluster; -}; - -function calculateCentroid(c1Size, c1Centroid, c2Size, c2Centroid) { - var newCentroid = [], - newSize = c1Size + c2Size, - n = c1Centroid.length, - i = -1; - while (++i < n) { - newCentroid[i] = (c1Size * c1Centroid[i] + c2Size * c2Centroid[i]) / newSize; - } - return newCentroid; -} -science.stats.iqr = function(x) { - var quartiles = science.stats.quantiles(x, [.25, .75]); - return quartiles[1] - quartiles[0]; -}; -// Based on org.apache.commons.math.analysis.interpolation.LoessInterpolator -// from http://commons.apache.org/math/ -science.stats.loess = function() { - var bandwidth = .3, - robustnessIters = 2, - accuracy = 1e-12; - - function smooth(xval, yval, weights) { - var n = xval.length, - i; - - if (n !== yval.length) throw {error: "Mismatched array lengths"}; - if (n == 0) throw {error: "At least one point required."}; - - if (arguments.length < 3) { - weights = []; - i = -1; while (++i < n) weights[i] = 1; - } - - science_stats_loessFiniteReal(xval); - science_stats_loessFiniteReal(yval); - science_stats_loessFiniteReal(weights); - science_stats_loessStrictlyIncreasing(xval); - - if (n == 1) return [yval[0]]; - if (n == 2) return [yval[0], yval[1]]; - - var bandwidthInPoints = Math.floor(bandwidth * n); - - if (bandwidthInPoints < 2) throw {error: "Bandwidth too small."}; - - var res = [], - residuals = [], - robustnessWeights = []; - - // Do an initial fit and 'robustnessIters' robustness iterations. - // This is equivalent to doing 'robustnessIters+1' robustness iterations - // starting with all robustness weights set to 1. - i = -1; while (++i < n) { - res[i] = 0; - residuals[i] = 0; - robustnessWeights[i] = 1; - } - - var iter = -1; - while (++iter <= robustnessIters) { - var bandwidthInterval = [0, bandwidthInPoints - 1]; - // At each x, compute a local weighted linear regression - var x; - i = -1; while (++i < n) { - x = xval[i]; - - // Find out the interval of source points on which - // a regression is to be made. - if (i > 0) { - science_stats_loessUpdateBandwidthInterval(xval, weights, i, bandwidthInterval); - } - - var ileft = bandwidthInterval[0], - iright = bandwidthInterval[1]; - - // Compute the point of the bandwidth interval that is - // farthest from x - var edge = (xval[i] - xval[ileft]) > (xval[iright] - xval[i]) ? ileft : iright; - - // Compute a least-squares linear fit weighted by - // the product of robustness weights and the tricube - // weight function. - // See http://en.wikipedia.org/wiki/Linear_regression - // (section "Univariate linear case") - // and http://en.wikipedia.org/wiki/Weighted_least_squares - // (section "Weighted least squares") - var sumWeights = 0, - sumX = 0, - sumXSquared = 0, - sumY = 0, - sumXY = 0, - denom = Math.abs(1 / (xval[edge] - x)); - - for (var k = ileft; k <= iright; ++k) { - var xk = xval[k], - yk = yval[k], - dist = k < i ? x - xk : xk - x, - w = science_stats_loessTricube(dist * denom) * robustnessWeights[k] * weights[k], - xkw = xk * w; - sumWeights += w; - sumX += xkw; - sumXSquared += xk * xkw; - sumY += yk * w; - sumXY += yk * xkw; - } - - var meanX = sumX / sumWeights, - meanY = sumY / sumWeights, - meanXY = sumXY / sumWeights, - meanXSquared = sumXSquared / sumWeights; - - var beta = (Math.sqrt(Math.abs(meanXSquared - meanX * meanX)) < accuracy) - ? 0 : ((meanXY - meanX * meanY) / (meanXSquared - meanX * meanX)); - - var alpha = meanY - beta * meanX; - - res[i] = beta * x + alpha; - residuals[i] = Math.abs(yval[i] - res[i]); - } - - // No need to recompute the robustness weights at the last - // iteration, they won't be needed anymore - if (iter === robustnessIters) { - break; - } - - // Recompute the robustness weights. - - // Find the median residual. - var sortedResiduals = residuals.slice(); - sortedResiduals.sort(); - var medianResidual = sortedResiduals[Math.floor(n / 2)]; - - if (Math.abs(medianResidual) < accuracy) - break; - - var arg, - w; - i = -1; while (++i < n) { - arg = residuals[i] / (6 * medianResidual); - robustnessWeights[i] = (arg >= 1) ? 0 : ((w = 1 - arg * arg) * w); - } - } - - return res; - } - - smooth.bandwidth = function(x) { - if (!arguments.length) return x; - bandwidth = x; - return smooth; - }; - - smooth.robustnessIterations = function(x) { - if (!arguments.length) return x; - robustnessIters = x; - return smooth; - }; - - smooth.accuracy = function(x) { - if (!arguments.length) return x; - accuracy = x; - return smooth; - }; - - return smooth; -}; - -function science_stats_loessFiniteReal(values) { - var n = values.length, - i = -1; - - while (++i < n) if (!isFinite(values[i])) return false; - - return true; -} - -function science_stats_loessStrictlyIncreasing(xval) { - var n = xval.length, - i = 0; - - while (++i < n) if (xval[i - 1] >= xval[i]) return false; - - return true; -} - -// Compute the tricube weight function. -// http://en.wikipedia.org/wiki/Local_regression#Weight_function -function science_stats_loessTricube(x) { - return (x = 1 - x * x * x) * x * x; -} - -// Given an index interval into xval that embraces a certain number of -// points closest to xval[i-1], update the interval so that it embraces -// the same number of points closest to xval[i], ignoring zero weights. -function science_stats_loessUpdateBandwidthInterval( - xval, weights, i, bandwidthInterval) { - - var left = bandwidthInterval[0], - right = bandwidthInterval[1]; - - // The right edge should be adjusted if the next point to the right - // is closer to xval[i] than the leftmost point of the current interval - var nextRight = science_stats_loessNextNonzero(weights, right); - if ((nextRight < xval.length) && (xval[nextRight] - xval[i]) < (xval[i] - xval[left])) { - var nextLeft = science_stats_loessNextNonzero(weights, left); - bandwidthInterval[0] = nextLeft; - bandwidthInterval[1] = nextRight; - } -} - -function science_stats_loessNextNonzero(weights, i) { - var j = i + 1; - while (j < weights.length && weights[j] === 0) j++; - return j; -} -// Welford's algorithm. -science.stats.mean = function(x) { - var n = x.length; - if (n === 0) return NaN; - var m = 0, - i = -1; - while (++i < n) m += (x[i] - m) / (i + 1); - return m; -}; -science.stats.median = function(x) { - return science.stats.quantiles(x, [.5])[0]; -}; -science.stats.mode = function(x) { - x = x.slice().sort(science.ascending); - var mode, - n = x.length, - i = -1, - l = i, - last = null, - max = 0, - tmp, - v; - while (++i < n) { - if ((v = x[i]) !== last) { - if ((tmp = i - l) > max) { - max = tmp; - mode = last; - } - last = v; - l = i; - } - } - return mode; -}; -// Uses R's quantile algorithm type=7. -science.stats.quantiles = function(d, quantiles) { - d = d.slice().sort(science.ascending); - var n_1 = d.length - 1; - return quantiles.map(function(q) { - if (q === 0) return d[0]; - else if (q === 1) return d[n_1]; - - var index = 1 + q * n_1, - lo = Math.floor(index), - h = index - lo, - a = d[lo - 1]; - - return h === 0 ? a : a + h * (d[lo] - a); - }); -}; -// Unbiased estimate of a sample's variance. -// Also known as the sample variance, where the denominator is n - 1. -science.stats.variance = function(x) { - var n = x.length; - if (n < 1) return NaN; - if (n === 1) return 0; - var mean = science.stats.mean(x), - i = -1, - s = 0; - while (++i < n) { - var v = x[i] - mean; - s += v * v; - } - return s / (n - 1); -}; -})() \ No newline at end of file diff --git a/lib/science/science.stats.min.js b/lib/science/science.stats.min.js deleted file mode 100644 index fd69f1343cdb97..00000000000000 --- a/lib/science/science.stats.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(){function h(a,b){var c=b+1;while(c=a[c])return!1;return!0}function d(a){var b=a.length,c=-1;while(++cd)return null;var e=[],f=[],g={},h=0,i=0,j,k,l;while(ie&&(e=f);return e},hamming:function(a,b){var c=a.length,d=-1,e=0;while(++d=-1?.5:0},triangular:function(a){return a<=1&&a>=-1?1-Math.abs(a):0},epanechnikov:function(a){return a<=1&&a>=-1?.75*(1-a*a):0},quartic:function(a){if(a<=1&&a>=-1){var b=1-a*a;return.9375*b*b}return 0},triweight:function(a){if(a<=1&&a>=-1){var b=1-a*a;return 35/32*b*b*b}return 0},gaussian:function(a){return 1/Math.sqrt(2*Math.PI)*Math.exp(-0.5*a*a)},cosine:function(a){return a<=1&&a>=-1?Math.PI/4*Math.cos(Math.PI/2*a):0}},science.stats.kde=function(){function d(d,e){var f=c.call(this,b);return d.map(function(c){var d=-1,e=0,g=b.length;while(++dh[p][q]&&(f[p]=q)}p=-1;while(++ph[k][q]&&(h[q][j]=h[j][q]=h[k][q]);break;case"complete":h[j][q]0&&g(h,j,l,r);var t=r[0],u=r[1],v=h[l]-h[t]>h[u]-h[l]?t:u,w=0,x=0,y=0,z=0,A=0,B=Math.abs(1/(h[v]-s));for(var C=t;C<=u;++C){var D=h[C],E=i[C],F=C=1?0:(G=1-Q*Q)*G}return n}var a=.3,b=2,c=1e-12;h.bandwidth=function(b){if(!arguments.length)return b;a=b;return h},h.robustnessIterations=function(a){if(!arguments.length)return a;b=a;return h},h.accuracy=function(a){if(!arguments.length)return a;c=a;return h};return h},science.stats.mean=function(a){var b=a.length;if(b===0)return NaN;var c=0,d=-1;while(++dg&&(g=h,b=f),f=i,e=d);return b},science.stats.quantiles=function(a,b){a=a.slice().sort(science.ascending);var c=a.length-1;return b.map(function(b){if(b===0)return a[0];if(b===1)return a[c];var d=1+b*c,e=Math.floor(d),f=d-e,g=a[e-1];return f===0?g:g+f*(a[e]-g)})},science.stats.variance=function(a){var b=a.length;if(b<1)return NaN;if(b===1)return 0;var c=science.stats.mean(a),d=-1,e=0;while(++d dist/package.js && rollup -c", + "test": "tape 'test/**/*-test.js'", + "prepublishOnly": "yarn test", + "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../d3/dist/d3.js d3.v${npm_package_version%%.*}.js && cp ../d3/dist/d3.min.js d3.v${npm_package_version%%.*}.min.js && git add d3.v${npm_package_version%%.*}.js d3.v${npm_package_version%%.*}.min.js && git commit -m \"d3 ${npm_package_version}\" && git push && cd - && zip -j dist/d3.zip -- LICENSE README.md API.md CHANGES.md dist/d3.js dist/d3.min.js" }, "devDependencies": { - "smash": "~0.0.8", - "uglify-js": "2.3.6", - "vows": "0.7.x" - }, - "scripts": { - "test": "node_modules/.bin/vows" + "json2module": "0.0", + "rimraf": "3", + "rollup": "2", + "rollup-plugin-ascii": "0.0", + "rollup-plugin-node-resolve": "5", + "rollup-plugin-terser": "7", + "tape": "4", + "tape-await": "0.1" }, - "licenses": [ - { - "type": "BSD", - "url": "https://github.com/mbostock/d3/blob/master/LICENSE" - } - ] + "dependencies": { + "d3-array": "2", + "d3-axis": "2", + "d3-brush": "2", + "d3-chord": "2", + "d3-color": "2", + "d3-contour": "2", + "d3-delaunay": "5", + "d3-dispatch": "2", + "d3-drag": "2", + "d3-dsv": "2", + "d3-ease": "2", + "d3-fetch": "2", + "d3-force": "2", + "d3-format": "2", + "d3-geo": "2", + "d3-hierarchy": "2", + "d3-interpolate": "2", + "d3-path": "2", + "d3-polygon": "2", + "d3-quadtree": "2", + "d3-random": "2", + "d3-scale": "3", + "d3-scale-chromatic": "2", + "d3-selection": "2", + "d3-shape": "2", + "d3-time": "2", + "d3-time-format": "3", + "d3-timer": "2", + "d3-transition": "2", + "d3-zoom": "2" + } } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000000000..3a6a4ecacd45f1 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,55 @@ +import ascii from "rollup-plugin-ascii"; +import node from "rollup-plugin-node-resolve"; +import {terser} from "rollup-plugin-terser"; +import * as meta from "./package.json"; + +const copyright = `// ${meta.homepage} v${meta.version} Copyright ${(new Date).getFullYear()} ${meta.author.name}`; + +function onwarn(message, warn) { + if (message.code === "CIRCULAR_DEPENDENCY") return; + warn(message); +} + +export default [ + { + input: "index.js", + external: Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)), + output: { + file: "dist/d3.node.js", + format: "cjs" + }, + onwarn + }, + { + input: "index.js", + plugins: [ + node(), + ascii() + ], + output: { + extend: true, + banner: copyright, + file: "dist/d3.js", + format: "umd", + indent: false, + name: "d3" + }, + onwarn + }, + { + input: "index.js", + plugins: [ + node(), + ascii(), + terser({output: {preamble: copyright}}) + ], + output: { + extend: true, + file: "dist/d3.min.js", + format: "umd", + indent: false, + name: "d3" + }, + onwarn + } +]; diff --git a/src/arrays/ascending.js b/src/arrays/ascending.js deleted file mode 100644 index 87699cc56d079a..00000000000000 --- a/src/arrays/ascending.js +++ /dev/null @@ -1,3 +0,0 @@ -d3.ascending = function(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; -}; diff --git a/src/arrays/bisect.js b/src/arrays/bisect.js deleted file mode 100644 index 09b87b8afcaf96..00000000000000 --- a/src/arrays/bisect.js +++ /dev/null @@ -1,28 +0,0 @@ -d3.bisector = function(f) { - return { - left: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (f.call(a, a[mid], mid) < x) lo = mid + 1; - else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (x < f.call(a, a[mid], mid)) hi = mid; - else lo = mid + 1; - } - return lo; - } - }; -}; - -var d3_bisector = d3.bisector(function(d) { return d; }); -d3.bisectLeft = d3_bisector.left; -d3.bisect = d3.bisectRight = d3_bisector.right; diff --git a/src/arrays/descending.js b/src/arrays/descending.js deleted file mode 100644 index 05034586ffe6ff..00000000000000 --- a/src/arrays/descending.js +++ /dev/null @@ -1,3 +0,0 @@ -d3.descending = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; -}; diff --git a/src/arrays/entries.js b/src/arrays/entries.js deleted file mode 100644 index 4ce014b82bae22..00000000000000 --- a/src/arrays/entries.js +++ /dev/null @@ -1,5 +0,0 @@ -d3.entries = function(map) { - var entries = []; - for (var key in map) entries.push({key: key, value: map[key]}); - return entries; -}; diff --git a/src/arrays/extent.js b/src/arrays/extent.js deleted file mode 100644 index a07ffea13b5fe9..00000000000000 --- a/src/arrays/extent.js +++ /dev/null @@ -1,21 +0,0 @@ -d3.extent = function(array, f) { - var i = -1, - n = array.length, - a, - b, - c; - if (arguments.length === 1) { - while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined; - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } else { - while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } - return [a, c]; -}; diff --git a/src/arrays/index.js b/src/arrays/index.js deleted file mode 100644 index fb7457b8da61ef..00000000000000 --- a/src/arrays/index.js +++ /dev/null @@ -1,23 +0,0 @@ -import "ascending"; -import "descending"; -import "min"; -import "max"; -import "extent"; -import "sum"; -import "mean"; -import "median"; -import "quantile"; -import "bisect"; -import "shuffle"; -import "permute"; -import "pairs"; -import "zip"; -import "transpose"; -import "keys"; -import "values"; -import "entries"; -import "merge"; -import "range"; -import "nest"; -import "map"; -import "set"; diff --git a/src/arrays/keys.js b/src/arrays/keys.js deleted file mode 100644 index c83ec8e15688b0..00000000000000 --- a/src/arrays/keys.js +++ /dev/null @@ -1,5 +0,0 @@ -d3.keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; -}; diff --git a/src/arrays/map.js b/src/arrays/map.js deleted file mode 100644 index 1f084da73ab8fb..00000000000000 --- a/src/arrays/map.js +++ /dev/null @@ -1,51 +0,0 @@ -import "../core/class"; - -d3.map = function(object) { - var map = new d3_Map; - if (object instanceof d3_Map) object.forEach(function(key, value) { map.set(key, value); }); - else for (var key in object) map.set(key, object[key]); - return map; -}; - -function d3_Map() {} - -d3_class(d3_Map, { - has: function(key) { - return d3_map_prefix + key in this; - }, - get: function(key) { - return this[d3_map_prefix + key]; - }, - set: function(key, value) { - return this[d3_map_prefix + key] = value; - }, - remove: function(key) { - key = d3_map_prefix + key; - return key in this && delete this[key]; - }, - keys: function() { - var keys = []; - this.forEach(function(key) { keys.push(key); }); - return keys; - }, - values: function() { - var values = []; - this.forEach(function(key, value) { values.push(value); }); - return values; - }, - entries: function() { - var entries = []; - this.forEach(function(key, value) { entries.push({key: key, value: value}); }); - return entries; - }, - forEach: function(f) { - for (var key in this) { - if (key.charCodeAt(0) === d3_map_prefixCode) { - f.call(this, key.substring(1), this[key]); - } - } - } -}); - -var d3_map_prefix = "\0", // prevent collision with built-ins - d3_map_prefixCode = d3_map_prefix.charCodeAt(0); diff --git a/src/arrays/max.js b/src/arrays/max.js deleted file mode 100644 index 4aac270ffdccfb..00000000000000 --- a/src/arrays/max.js +++ /dev/null @@ -1,14 +0,0 @@ -d3.max = function(array, f) { - var i = -1, - n = array.length, - a, - b; - if (arguments.length === 1) { - while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && b > a) a = b; - } else { - while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; - } - return a; -}; diff --git a/src/arrays/mean.js b/src/arrays/mean.js deleted file mode 100644 index 25b85faa8e00df..00000000000000 --- a/src/arrays/mean.js +++ /dev/null @@ -1,15 +0,0 @@ -import "../math/number"; - -d3.mean = function(array, f) { - var n = array.length, - a, - m = 0, - i = -1, - j = 0; - if (arguments.length === 1) { - while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; - } else { - while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; - } - return j ? m : undefined; -}; diff --git a/src/arrays/median.js b/src/arrays/median.js deleted file mode 100644 index 0366a94fe6553d..00000000000000 --- a/src/arrays/median.js +++ /dev/null @@ -1,9 +0,0 @@ -import "../math/number"; -import "ascending"; -import "quantile"; - -d3.median = function(array, f) { - if (arguments.length > 1) array = array.map(f); - array = array.filter(d3_number); - return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined; -}; diff --git a/src/arrays/merge.js b/src/arrays/merge.js deleted file mode 100644 index d7307181107d2d..00000000000000 --- a/src/arrays/merge.js +++ /dev/null @@ -1,3 +0,0 @@ -d3.merge = function(arrays) { - return Array.prototype.concat.apply([], arrays); -}; diff --git a/src/arrays/min.js b/src/arrays/min.js deleted file mode 100644 index f566ce96306071..00000000000000 --- a/src/arrays/min.js +++ /dev/null @@ -1,14 +0,0 @@ -d3.min = function(array, f) { - var i = -1, - n = array.length, - a, - b; - if (arguments.length === 1) { - while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && a > b) a = b; - } else { - while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; - } - return a; -}; diff --git a/src/arrays/nest.js b/src/arrays/nest.js deleted file mode 100644 index 859add7be3349c..00000000000000 --- a/src/arrays/nest.js +++ /dev/null @@ -1,97 +0,0 @@ -import "map"; - -d3.nest = function() { - var nest = {}, - keys = [], - sortKeys = [], - sortValues, - rollup; - - function map(mapType, array, depth) { - if (depth >= keys.length) return rollup - ? rollup.call(nest, array) : (sortValues - ? array.sort(sortValues) - : array); - - var i = -1, - n = array.length, - key = keys[depth++], - keyValue, - object, - setter, - valuesByKey = new d3_Map, - values; - - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(object = array[i]))) { - values.push(object); - } else { - valuesByKey.set(keyValue, [object]); - } - } - - if (mapType) { - object = mapType(); - setter = function(keyValue, values) { - object.set(keyValue, map(mapType, values, depth)); - }; - } else { - object = {}; - setter = function(keyValue, values) { - object[keyValue] = map(mapType, values, depth); - }; - } - - valuesByKey.forEach(setter); - return object; - } - - function entries(map, depth) { - if (depth >= keys.length) return map; - - var array = [], - sortKey = sortKeys[depth++]; - - map.forEach(function(key, keyMap) { - array.push({key: key, values: entries(keyMap, depth)}); - }); - - return sortKey - ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) - : array; - } - - nest.map = function(array, mapType) { - return map(mapType, array, 0); - }; - - nest.entries = function(array) { - return entries(map(d3.map, array, 0), 0); - }; - - nest.key = function(d) { - keys.push(d); - return nest; - }; - - // Specifies the order for the most-recently specified key. - // Note: only applies to entries. Map keys are unordered! - nest.sortKeys = function(order) { - sortKeys[keys.length - 1] = order; - return nest; - }; - - // Specifies the order for leaf values. - // Applies to both maps and entries array. - nest.sortValues = function(order) { - sortValues = order; - return nest; - }; - - nest.rollup = function(f) { - rollup = f; - return nest; - }; - - return nest; -}; diff --git a/src/arrays/pairs.js b/src/arrays/pairs.js deleted file mode 100644 index e270f957cda345..00000000000000 --- a/src/arrays/pairs.js +++ /dev/null @@ -1,5 +0,0 @@ -d3.pairs = function(array) { - var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); - while (i < n) pairs[i] = [p0 = p1, p1 = array[++i]]; - return pairs; -}; diff --git a/src/arrays/permute.js b/src/arrays/permute.js deleted file mode 100644 index f27d2c9d261fa6..00000000000000 --- a/src/arrays/permute.js +++ /dev/null @@ -1,5 +0,0 @@ -d3.permute = function(array, indexes) { - var i = indexes.length, permutes = new Array(i); - while (i--) permutes[i] = array[indexes[i]]; - return permutes; -}; diff --git a/src/arrays/quantile.js b/src/arrays/quantile.js deleted file mode 100644 index 67fe9fd71cd314..00000000000000 --- a/src/arrays/quantile.js +++ /dev/null @@ -1,8 +0,0 @@ -// R-7 per -d3.quantile = function(values, p) { - var H = (values.length - 1) * p + 1, - h = Math.floor(H), - v = +values[h - 1], - e = H - h; - return e ? v + e * (values[h] - v) : v; -}; diff --git a/src/arrays/range.js b/src/arrays/range.js deleted file mode 100644 index 38fbc05f5e1f17..00000000000000 --- a/src/arrays/range.js +++ /dev/null @@ -1,24 +0,0 @@ -d3.range = function(start, stop, step) { - if (arguments.length < 3) { - step = 1; - if (arguments.length < 2) { - stop = start; - start = 0; - } - } - if ((stop - start) / step === Infinity) throw new Error("infinite range"); - var range = [], - k = d3_range_integerScale(Math.abs(step)), - i = -1, - j; - start *= k, stop *= k, step *= k; - if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); - else while ((j = start + step * ++i) < stop) range.push(j / k); - return range; -}; - -function d3_range_integerScale(x) { - var k = 1; - while (x * k % 1) k *= 10; - return k; -} diff --git a/src/arrays/set.js b/src/arrays/set.js deleted file mode 100644 index e74ada0e937b2c..00000000000000 --- a/src/arrays/set.js +++ /dev/null @@ -1,38 +0,0 @@ -import "../core/class"; -import "map"; - -d3.set = function(array) { - var set = new d3_Set; - if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); - return set; -}; - -function d3_Set() {} - -d3_class(d3_Set, { - has: function(value) { - return d3_map_prefix + value in this; - }, - add: function(value) { - this[d3_map_prefix + value] = true; - return value; - }, - remove: function(value) { - value = d3_map_prefix + value; - return value in this && delete this[value]; - }, - values: function() { - var values = []; - this.forEach(function(value) { - values.push(value); - }); - return values; - }, - forEach: function(f) { - for (var value in this) { - if (value.charCodeAt(0) === d3_map_prefixCode) { - f.call(this, value.substring(1)); - } - } - } -}); diff --git a/src/arrays/shuffle.js b/src/arrays/shuffle.js deleted file mode 100644 index 3369f76bc338f9..00000000000000 --- a/src/arrays/shuffle.js +++ /dev/null @@ -1,8 +0,0 @@ -d3.shuffle = function(array) { - var m = array.length, t, i; - while (m) { - i = Math.random() * m-- | 0; - t = array[m], array[m] = array[i], array[i] = t; - } - return array; -}; diff --git a/src/arrays/sum.js b/src/arrays/sum.js deleted file mode 100644 index b9af6e8a783288..00000000000000 --- a/src/arrays/sum.js +++ /dev/null @@ -1,14 +0,0 @@ -d3.sum = function(array, f) { - var s = 0, - n = array.length, - a, - i = -1; - - if (arguments.length === 1) { - while (++i < n) if (!isNaN(a = +array[i])) s += a; - } else { - while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; - } - - return s; -}; diff --git a/src/arrays/transpose.js b/src/arrays/transpose.js deleted file mode 100644 index 999c54306893cb..00000000000000 --- a/src/arrays/transpose.js +++ /dev/null @@ -1,5 +0,0 @@ -import "zip"; - -d3.transpose = function(matrix) { - return d3.zip.apply(d3, matrix); -}; diff --git a/src/arrays/values.js b/src/arrays/values.js deleted file mode 100644 index 299d30433caa31..00000000000000 --- a/src/arrays/values.js +++ /dev/null @@ -1,5 +0,0 @@ -d3.values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; -}; diff --git a/src/arrays/zip.js b/src/arrays/zip.js deleted file mode 100644 index 302ec4a5f3ef3a..00000000000000 --- a/src/arrays/zip.js +++ /dev/null @@ -1,15 +0,0 @@ -import "min"; - -d3.zip = function() { - if (!(n = arguments.length)) return []; - for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m;) { - for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n;) { - zip[j] = arguments[j][i]; - } - } - return zips; -}; - -function d3_zipLength(d) { - return d.length; -} diff --git a/src/behavior/behavior.js b/src/behavior/behavior.js deleted file mode 100644 index 39633b10599fa4..00000000000000 --- a/src/behavior/behavior.js +++ /dev/null @@ -1 +0,0 @@ -d3.behavior = {}; diff --git a/src/behavior/drag.js b/src/behavior/drag.js deleted file mode 100644 index 4f402208893cbe..00000000000000 --- a/src/behavior/drag.js +++ /dev/null @@ -1,77 +0,0 @@ -import "../core/document"; -import "../core/rebind"; -import "../event/drag"; -import "../event/event"; -import "../event/mouse"; -import "../event/touches"; -import "behavior"; - -d3.behavior.drag = function() { - var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), - origin = null, - mousedown = dragstart(d3_noop, d3.mouse, "mousemove", "mouseup"), - touchstart = dragstart(touchid, touchposition, "touchmove", "touchend"); - - function drag() { - this.on("mousedown.drag", mousedown) - .on("touchstart.drag", touchstart); - } - - function touchid() { - return d3.event.changedTouches[0].identifier; - } - - function touchposition(parent, id) { - return d3.touches(parent).filter(function(p) { return p.identifier === id; })[0]; - } - - function dragstart(id, position, move, end) { - return function() { - var target = this, - parent = target.parentNode, - event_ = event.of(target, arguments), - eventTarget = d3.event.target, - eventId = id(), - drag = eventId == null ? "drag" : "drag-" + eventId, - origin_ = position(parent, eventId), - dragged = 0, - offset, - w = d3.select(d3_window).on(move + "." + drag, moved).on(end + "." + drag, ended), - dragRestore = d3_event_dragSuppress(); - - if (origin) { - offset = origin.apply(target, arguments); - offset = [offset.x - origin_[0], offset.y - origin_[1]]; - } else { - offset = [0, 0]; - } - - event_({type: "dragstart"}); - - function moved() { - var p = position(parent, eventId), - dx = p[0] - origin_[0], - dy = p[1] - origin_[1]; - - dragged |= dx | dy; - origin_ = p; - - event_({type: "drag", x: p[0] + offset[0], y: p[1] + offset[1], dx: dx, dy: dy}); - } - - function ended() { - w.on(move + "." + drag, null).on(end + "." + drag, null); - dragRestore(dragged && d3.event.target === eventTarget); - event_({type: "dragend"}); - } - }; - } - - drag.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return drag; - }; - - return d3.rebind(drag, event, "on"); -}; diff --git a/src/behavior/index.js b/src/behavior/index.js deleted file mode 100644 index 5ce09321d28f75..00000000000000 --- a/src/behavior/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import "behavior"; -import "drag"; -import "zoom"; diff --git a/src/behavior/zoom.js b/src/behavior/zoom.js deleted file mode 100644 index 8ad326a7ec529b..00000000000000 --- a/src/behavior/zoom.js +++ /dev/null @@ -1,323 +0,0 @@ -import "../core/document"; -import "../core/rebind"; -import "../event/drag"; -import "../event/event"; -import "../event/mouse"; -import "../event/touches"; -import "../selection/selection"; -import "../interpolate/zoom"; -import "behavior"; - -d3.behavior.zoom = function() { - var view = {x: 0, y: 0, k: 1}, - translate0, // translate when we started zooming (to avoid drift) - center, // desired position of translate0 after zooming - size = [960, 500], // viewport size; required for zoom interpolation - scaleExtent = d3_behavior_zoomInfinity, - mousedown = "mousedown.zoom", - mousemove = "mousemove.zoom", - mouseup = "mouseup.zoom", - mousewheelTimer, - touchstart = "touchstart.zoom", - touchtime, // time of last touchstart (to detect double-tap) - event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), - x0, - x1, - y0, - y1; - - function zoom(g) { - g .on(mousedown, mousedowned) - .on(d3_behavior_zoomWheel + ".zoom", mousewheeled) - .on(mousemove, mousewheelreset) - .on("dblclick.zoom", dblclicked) - .on(touchstart, touchstarted); - } - - zoom.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), - view1 = view; - if (d3_transitionInheritId) { - d3.select(this).transition() - .each("start.zoom", function() { - view = this.__chart__ || {x: 0, y: 0, k: 1}; // pre-transition state - zoomstarted(event_); - }) - .tween("zoom:zoom", function() { - var dx = size[0], - dy = size[1], - cx = dx / 2, - cy = dy / 2, - i = d3.interpolateZoom( - [(cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k], - [(cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k] - ); - return function(t) { - var l = i(t), k = dx / l[2]; - this.__chart__ = view = {x: cx - l[0] * k, y: cy - l[1] * k, k: k}; - zoomed(event_); - }; - }) - .each("end.zoom", function() { - zoomended(event_); - }); - } else { - this.__chart__ = view; - zoomstarted(event_); - zoomed(event_); - zoomended(event_); - } - }); - } - - zoom.translate = function(_) { - if (!arguments.length) return [view.x, view.y]; - view = {x: +_[0], y: +_[1], k: view.k}; // copy-on-write - rescale(); - return zoom; - }; - - zoom.scale = function(_) { - if (!arguments.length) return view.k; - view = {x: view.x, y: view.y, k: +_}; // copy-on-write - rescale(); - return zoom; - }; - - zoom.scaleExtent = function(_) { - if (!arguments.length) return scaleExtent; - scaleExtent = _ == null ? d3_behavior_zoomInfinity : [+_[0], +_[1]]; - return zoom; - }; - - zoom.center = function(_) { - if (!arguments.length) return center; - center = _ && [+_[0], +_[1]]; - return zoom; - }; - - zoom.size = function(_) { - if (!arguments.length) return size; - size = _ && [+_[0], +_[1]]; - return zoom; - }; - - zoom.x = function(z) { - if (!arguments.length) return x1; - x1 = z; - x0 = z.copy(); - view = {x: 0, y: 0, k: 1}; // copy-on-write - return zoom; - }; - - zoom.y = function(z) { - if (!arguments.length) return y1; - y1 = z; - y0 = z.copy(); - view = {x: 0, y: 0, k: 1}; // copy-on-write - return zoom; - }; - - function location(p) { - return [(p[0] - view.x) / view.k, (p[1] - view.y) / view.k]; - } - - function point(l) { - return [l[0] * view.k + view.x, l[1] * view.k + view.y]; - } - - function scaleTo(s) { - view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); - } - - function translateTo(p, l) { - l = point(l); - view.x += p[0] - l[0]; - view.y += p[1] - l[1]; - } - - function rescale() { - if (x1) x1.domain(x0.range().map(function(x) { return (x - view.x) / view.k; }).map(x0.invert)); - if (y1) y1.domain(y0.range().map(function(y) { return (y - view.y) / view.k; }).map(y0.invert)); - } - - function zoomstarted(event) { - event({type: "zoomstart"}); - } - - function zoomed(event) { - rescale(); - event({type: "zoom", scale: view.k, translate: [view.x, view.y]}); - } - - function zoomended(event) { - event({type: "zoomend"}); - } - - function mousedowned() { - var target = this, - event_ = event.of(target, arguments), - eventTarget = d3.event.target, - dragged = 0, - w = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), - l = location(d3.mouse(target)), - dragRestore = d3_event_dragSuppress(); - - d3_selection_interrupt.call(target); - zoomstarted(event_); - - function moved() { - dragged = 1; - translateTo(d3.mouse(target), l); - zoomed(event_); - } - - function ended() { - w.on(mousemove, d3_window === target ? mousewheelreset : null).on(mouseup, null); - dragRestore(dragged && d3.event.target === eventTarget); - zoomended(event_); - } - } - - // These closures persist for as long as at least one touch is active. - function touchstarted() { - var target = this, - event_ = event.of(target, arguments), - locations0 = {}, // touchstart locations - distance0 = 0, // distance² between initial touches - scale0, // scale when we started touching - eventId = d3.event.changedTouches[0].identifier, - touchmove = "touchmove.zoom-" + eventId, - touchend = "touchend.zoom-" + eventId, - w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), - t = d3.select(target).on(mousedown, null).on(touchstart, started), // prevent duplicate events - dragRestore = d3_event_dragSuppress(); - - d3_selection_interrupt.call(target); - started(); - zoomstarted(event_); - - // Updates locations of any touches in locations0. - function relocate() { - var touches = d3.touches(target); - scale0 = view.k; - touches.forEach(function(t) { - if (t.identifier in locations0) locations0[t.identifier] = location(t); - }); - return touches; - } - - // Temporarily override touchstart while gesture is active. - function started() { - // Only track touches started on the target element. - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - locations0[changed[i].identifier] = null; - } - - var touches = relocate(), - now = Date.now(); - - if (touches.length === 1) { - if (now - touchtime < 500) { // dbltap - var p = touches[0], l = locations0[p.identifier]; - scaleTo(view.k * 2); - translateTo(p, l); - d3_eventPreventDefault(); - zoomed(event_); - } - touchtime = now; - } else if (touches.length > 1) { - var p = touches[0], q = touches[1], - dx = p[0] - q[0], dy = p[1] - q[1]; - distance0 = dx * dx + dy * dy; - } - } - - function moved() { - var touches = d3.touches(target), - p0, l0, - p1, l1; - for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { - p1 = touches[i]; - if (l1 = locations0[p1.identifier]) { - if (l0) break; - p0 = p1, l0 = l1; - } - } - - if (l1) { - var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, - scale1 = distance0 && Math.sqrt(distance1 / distance0); - p0 = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; - l0 = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; - scaleTo(scale1 * scale0); - } - - touchtime = null; - translateTo(p0, l0); - zoomed(event_); - } - - function ended() { - // If there are any globally-active touches remaining, remove the ended - // touches from locations0. - if (d3.event.touches.length) { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - delete locations0[changed[i].identifier]; - } - // If locations0 is not empty, then relocate and continue listening for - // touchmove and touchend. - for (var identifier in locations0) { - return void relocate(); // locations may have detached due to rotation - } - } - // Otherwise, remove touchmove and touchend listeners. - w.on(touchmove, null).on(touchend, null); - t.on(mousedown, mousedowned).on(touchstart, touchstarted); - dragRestore(); - zoomended(event_); - } - } - - function mousewheeled() { - var event_ = event.of(this, arguments); - if (mousewheelTimer) clearTimeout(mousewheelTimer); - else d3_selection_interrupt.call(this), zoomstarted(event_); - mousewheelTimer = setTimeout(function() { mousewheelTimer = null; zoomended(event_); }, 50); - d3_eventPreventDefault(); - var point = center || d3.mouse(this); - if (!translate0) translate0 = location(point); - scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); - translateTo(point, translate0); - zoomed(event_); - } - - function mousewheelreset() { - translate0 = null; - } - - function dblclicked() { - var event_ = event.of(this, arguments), - p = d3.mouse(this), - l = location(p), - k = Math.log(view.k) / Math.LN2; - zoomstarted(event_); - scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); - translateTo(p, l); - zoomed(event_); - zoomended(event_); - } - - return d3.rebind(zoom, event, "on"); -}; - -var d3_behavior_zoomInfinity = [0, Infinity]; // default scale extent - -// https://developer.mozilla.org/en-US/docs/Mozilla_event_reference/wheel -var d3_behavior_zoomDelta, d3_behavior_zoomWheel - = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); }, "wheel") - : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { return d3.event.wheelDelta; }, "mousewheel") - : (d3_behavior_zoomDelta = function() { return -d3.event.detail; }, "MozMousePixelScroll"); diff --git a/src/color/color.js b/src/color/color.js deleted file mode 100644 index 396d1b1e917256..00000000000000 --- a/src/color/color.js +++ /dev/null @@ -1,5 +0,0 @@ -function d3_Color() {} - -d3_Color.prototype.toString = function() { - return this.rgb() + ""; -}; diff --git a/src/color/hcl.js b/src/color/hcl.js deleted file mode 100644 index 9b42fff9f13476..00000000000000 --- a/src/color/hcl.js +++ /dev/null @@ -1,42 +0,0 @@ -import "../math/trigonometry"; -import "color"; -import "lab"; -import "rgb"; - -d3.hcl = function(h, c, l) { - return arguments.length === 1 - ? (h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) - : (h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) - : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b))) - : d3_hcl(+h, +c, +l); -}; - -function d3_hcl(h, c, l) { - return new d3_Hcl(h, c, l); -} - -function d3_Hcl(h, c, l) { - this.h = h; - this.c = c; - this.l = l; -} - -var d3_hclPrototype = d3_Hcl.prototype = new d3_Color; - -d3_hclPrototype.brighter = function(k) { - return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); -}; - -d3_hclPrototype.darker = function(k) { - return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); -}; - -d3_hclPrototype.rgb = function() { - return d3_hcl_lab(this.h, this.c, this.l).rgb(); -}; - -function d3_hcl_lab(h, c, l) { - if (isNaN(h)) h = 0; - if (isNaN(c)) c = 0; - return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); -} diff --git a/src/color/hsl.js b/src/color/hsl.js deleted file mode 100644 index 7d7b71e55d664a..00000000000000 --- a/src/color/hsl.js +++ /dev/null @@ -1,64 +0,0 @@ -import "color"; -import "rgb"; - -d3.hsl = function(h, s, l) { - return arguments.length === 1 - ? (h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) - : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl)) - : d3_hsl(+h, +s, +l); -}; - -function d3_hsl(h, s, l) { - return new d3_Hsl(h, s, l); -} - -function d3_Hsl(h, s, l) { - this.h = h; - this.s = s; - this.l = l; -} - -var d3_hslPrototype = d3_Hsl.prototype = new d3_Color; - -d3_hslPrototype.brighter = function(k) { - k = Math.pow(0.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, this.l / k); -}; - -d3_hslPrototype.darker = function(k) { - k = Math.pow(0.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, k * this.l); -}; - -d3_hslPrototype.rgb = function() { - return d3_hsl_rgb(this.h, this.s, this.l); -}; - -function d3_hsl_rgb(h, s, l) { - var m1, - m2; - - /* Some simple corrections for h, s and l. */ - h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; - s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; - l = l < 0 ? 0 : l > 1 ? 1 : l; - - /* From FvD 13.37, CSS Color Module Level 3 */ - m2 = l <= .5 ? l * (1 + s) : l + s - l * s; - m1 = 2 * l - m2; - - function v(h) { - if (h > 360) h -= 360; - else if (h < 0) h += 360; - if (h < 60) return m1 + (m2 - m1) * h / 60; - if (h < 180) return m2; - if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; - return m1; - } - - function vv(h) { - return Math.round(v(h) * 255); - } - - return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); -} diff --git a/src/color/index.js b/src/color/index.js deleted file mode 100644 index 3be3854c99d186..00000000000000 --- a/src/color/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import "color"; -import "rgb"; -import "hsl"; -import "hcl"; -import "lab"; -import "xyz"; diff --git a/src/color/lab.js b/src/color/lab.js deleted file mode 100644 index df0f23072682e8..00000000000000 --- a/src/color/lab.js +++ /dev/null @@ -1,68 +0,0 @@ -import "../math/trigonometry"; -import "color"; -import "hcl"; -import "rgb"; - -d3.lab = function(l, a, b) { - return arguments.length === 1 - ? (l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) - : (l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) - : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b))) - : d3_lab(+l, +a, +b); -}; - -function d3_lab(l, a, b) { - return new d3_Lab(l, a, b); -} - -function d3_Lab(l, a, b) { - this.l = l; - this.a = a; - this.b = b; -} - -// Corresponds roughly to RGB brighter/darker -var d3_lab_K = 18; - -// D65 standard referent -var d3_lab_X = 0.950470, - d3_lab_Y = 1, - d3_lab_Z = 1.088830; - -var d3_labPrototype = d3_Lab.prototype = new d3_Color; - -d3_labPrototype.brighter = function(k) { - return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); -}; - -d3_labPrototype.darker = function(k) { - return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); -}; - -d3_labPrototype.rgb = function() { - return d3_lab_rgb(this.l, this.a, this.b); -}; - -function d3_lab_rgb(l, a, b) { - var y = (l + 16) / 116, - x = y + a / 500, - z = y - b / 200; - x = d3_lab_xyz(x) * d3_lab_X; - y = d3_lab_xyz(y) * d3_lab_Y; - z = d3_lab_xyz(z) * d3_lab_Z; - return d3_rgb( - d3_xyz_rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), - d3_xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), - d3_xyz_rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z) - ); -} - -function d3_lab_hcl(l, a, b) { - return l > 0 - ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) - : d3_hcl(NaN, NaN, l); -} - -function d3_lab_xyz(x) { - return x > 0.206893034 ? x * x * x : (x - 4 / 29) / 7.787037; -} diff --git a/src/color/rgb.js b/src/color/rgb.js deleted file mode 100644 index aebb0290905077..00000000000000 --- a/src/color/rgb.js +++ /dev/null @@ -1,309 +0,0 @@ -import "../arrays/map"; -import "color"; -import "hsl"; -import "lab"; -import "xyz"; - -d3.rgb = function(r, g, b) { - return arguments.length === 1 - ? (r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) - : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb)) - : d3_rgb(~~r, ~~g, ~~b); -}; - -function d3_rgbNumber(value) { - return d3_rgb(value >> 16, value >> 8 & 0xff, value & 0xff); -} - -function d3_rgbString(value) { - return d3_rgbNumber(value) + ""; -} - -function d3_rgb(r, g, b) { - return new d3_Rgb(r, g, b); -} - -function d3_Rgb(r, g, b) { - this.r = r; - this.g = g; - this.b = b; -} - -var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color; - -d3_rgbPrototype.brighter = function(k) { - k = Math.pow(0.7, arguments.length ? k : 1); - var r = this.r, - g = this.g, - b = this.b, - i = 30; - if (!r && !g && !b) return d3_rgb(i, i, i); - if (r && r < i) r = i; - if (g && g < i) g = i; - if (b && b < i) b = i; - return d3_rgb(Math.min(255, ~~(r / k)), Math.min(255, ~~(g / k)), Math.min(255, ~~(b / k))); -}; - -d3_rgbPrototype.darker = function(k) { - k = Math.pow(0.7, arguments.length ? k : 1); - return d3_rgb(~~(k * this.r), ~~(k * this.g), ~~(k * this.b)); -}; - -d3_rgbPrototype.hsl = function() { - return d3_rgb_hsl(this.r, this.g, this.b); -}; - -d3_rgbPrototype.toString = function() { - return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); -}; - -function d3_rgb_hex(v) { - return v < 0x10 - ? "0" + Math.max(0, v).toString(16) - : Math.min(255, v).toString(16); -} - -function d3_rgb_parse(format, rgb, hsl) { - var r = 0, // red channel; int in [0, 255] - g = 0, // green channel; int in [0, 255] - b = 0, // blue channel; int in [0, 255] - m1, // CSS color specification match - m2, // CSS color specification type (e.g., rgb) - name; - - /* Handle hsl, rgb. */ - m1 = /([a-z]+)\((.*)\)/i.exec(format); - if (m1) { - m2 = m1[2].split(","); - switch (m1[1]) { - case "hsl": { - return hsl( - parseFloat(m2[0]), // degrees - parseFloat(m2[1]) / 100, // percentage - parseFloat(m2[2]) / 100 // percentage - ); - } - case "rgb": { - return rgb( - d3_rgb_parseNumber(m2[0]), - d3_rgb_parseNumber(m2[1]), - d3_rgb_parseNumber(m2[2]) - ); - } - } - } - - /* Named colors. */ - if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b); - - /* Hexadecimal colors: #rgb and #rrggbb. */ - if (format != null && format.charAt(0) === "#") { - if (format.length === 4) { - r = format.charAt(1); r += r; - g = format.charAt(2); g += g; - b = format.charAt(3); b += b; - } else if (format.length === 7) { - r = format.substring(1, 3); - g = format.substring(3, 5); - b = format.substring(5, 7); - } - r = parseInt(r, 16); - g = parseInt(g, 16); - b = parseInt(b, 16); - } - - return rgb(r, g, b); -} - -function d3_rgb_hsl(r, g, b) { - var min = Math.min(r /= 255, g /= 255, b /= 255), - max = Math.max(r, g, b), - d = max - min, - h, - s, - l = (max + min) / 2; - if (d) { - s = l < .5 ? d / (max + min) : d / (2 - max - min); - if (r == max) h = (g - b) / d + (g < b ? 6 : 0); - else if (g == max) h = (b - r) / d + 2; - else h = (r - g) / d + 4; - h *= 60; - } else { - h = NaN; - s = l > 0 && l < 1 ? 0 : h; - } - return d3_hsl(h, s, l); -} - -function d3_rgb_lab(r, g, b) { - r = d3_rgb_xyz(r); - g = d3_rgb_xyz(g); - b = d3_rgb_xyz(b); - var x = d3_xyz_lab((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / d3_lab_X), - y = d3_xyz_lab((0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / d3_lab_Y), - z = d3_xyz_lab((0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / d3_lab_Z); - return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); -} - -function d3_rgb_xyz(r) { - return (r /= 255) <= 0.04045 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4); -} - -function d3_rgb_parseNumber(c) { // either integer or percentage - var f = parseFloat(c); - return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; -} - -var d3_rgb_names = d3.map({ - aliceblue: 0xf0f8ff, - antiquewhite: 0xfaebd7, - aqua: 0x00ffff, - aquamarine: 0x7fffd4, - azure: 0xf0ffff, - beige: 0xf5f5dc, - bisque: 0xffe4c4, - black: 0x000000, - blanchedalmond: 0xffebcd, - blue: 0x0000ff, - blueviolet: 0x8a2be2, - brown: 0xa52a2a, - burlywood: 0xdeb887, - cadetblue: 0x5f9ea0, - chartreuse: 0x7fff00, - chocolate: 0xd2691e, - coral: 0xff7f50, - cornflowerblue: 0x6495ed, - cornsilk: 0xfff8dc, - crimson: 0xdc143c, - cyan: 0x00ffff, - darkblue: 0x00008b, - darkcyan: 0x008b8b, - darkgoldenrod: 0xb8860b, - darkgray: 0xa9a9a9, - darkgreen: 0x006400, - darkgrey: 0xa9a9a9, - darkkhaki: 0xbdb76b, - darkmagenta: 0x8b008b, - darkolivegreen: 0x556b2f, - darkorange: 0xff8c00, - darkorchid: 0x9932cc, - darkred: 0x8b0000, - darksalmon: 0xe9967a, - darkseagreen: 0x8fbc8f, - darkslateblue: 0x483d8b, - darkslategray: 0x2f4f4f, - darkslategrey: 0x2f4f4f, - darkturquoise: 0x00ced1, - darkviolet: 0x9400d3, - deeppink: 0xff1493, - deepskyblue: 0x00bfff, - dimgray: 0x696969, - dimgrey: 0x696969, - dodgerblue: 0x1e90ff, - firebrick: 0xb22222, - floralwhite: 0xfffaf0, - forestgreen: 0x228b22, - fuchsia: 0xff00ff, - gainsboro: 0xdcdcdc, - ghostwhite: 0xf8f8ff, - gold: 0xffd700, - goldenrod: 0xdaa520, - gray: 0x808080, - green: 0x008000, - greenyellow: 0xadff2f, - grey: 0x808080, - honeydew: 0xf0fff0, - hotpink: 0xff69b4, - indianred: 0xcd5c5c, - indigo: 0x4b0082, - ivory: 0xfffff0, - khaki: 0xf0e68c, - lavender: 0xe6e6fa, - lavenderblush: 0xfff0f5, - lawngreen: 0x7cfc00, - lemonchiffon: 0xfffacd, - lightblue: 0xadd8e6, - lightcoral: 0xf08080, - lightcyan: 0xe0ffff, - lightgoldenrodyellow: 0xfafad2, - lightgray: 0xd3d3d3, - lightgreen: 0x90ee90, - lightgrey: 0xd3d3d3, - lightpink: 0xffb6c1, - lightsalmon: 0xffa07a, - lightseagreen: 0x20b2aa, - lightskyblue: 0x87cefa, - lightslategray: 0x778899, - lightslategrey: 0x778899, - lightsteelblue: 0xb0c4de, - lightyellow: 0xffffe0, - lime: 0x00ff00, - limegreen: 0x32cd32, - linen: 0xfaf0e6, - magenta: 0xff00ff, - maroon: 0x800000, - mediumaquamarine: 0x66cdaa, - mediumblue: 0x0000cd, - mediumorchid: 0xba55d3, - mediumpurple: 0x9370db, - mediumseagreen: 0x3cb371, - mediumslateblue: 0x7b68ee, - mediumspringgreen: 0x00fa9a, - mediumturquoise: 0x48d1cc, - mediumvioletred: 0xc71585, - midnightblue: 0x191970, - mintcream: 0xf5fffa, - mistyrose: 0xffe4e1, - moccasin: 0xffe4b5, - navajowhite: 0xffdead, - navy: 0x000080, - oldlace: 0xfdf5e6, - olive: 0x808000, - olivedrab: 0x6b8e23, - orange: 0xffa500, - orangered: 0xff4500, - orchid: 0xda70d6, - palegoldenrod: 0xeee8aa, - palegreen: 0x98fb98, - paleturquoise: 0xafeeee, - palevioletred: 0xdb7093, - papayawhip: 0xffefd5, - peachpuff: 0xffdab9, - peru: 0xcd853f, - pink: 0xffc0cb, - plum: 0xdda0dd, - powderblue: 0xb0e0e6, - purple: 0x800080, - red: 0xff0000, - rosybrown: 0xbc8f8f, - royalblue: 0x4169e1, - saddlebrown: 0x8b4513, - salmon: 0xfa8072, - sandybrown: 0xf4a460, - seagreen: 0x2e8b57, - seashell: 0xfff5ee, - sienna: 0xa0522d, - silver: 0xc0c0c0, - skyblue: 0x87ceeb, - slateblue: 0x6a5acd, - slategray: 0x708090, - slategrey: 0x708090, - snow: 0xfffafa, - springgreen: 0x00ff7f, - steelblue: 0x4682b4, - tan: 0xd2b48c, - teal: 0x008080, - thistle: 0xd8bfd8, - tomato: 0xff6347, - turquoise: 0x40e0d0, - violet: 0xee82ee, - wheat: 0xf5deb3, - white: 0xffffff, - whitesmoke: 0xf5f5f5, - yellow: 0xffff00, - yellowgreen: 0x9acd32 -}); - -d3_rgb_names.forEach(function(key, value) { - d3_rgb_names.set(key, d3_rgbNumber(value)); -}); diff --git a/src/color/xyz.js b/src/color/xyz.js deleted file mode 100644 index 30e79ab412bf05..00000000000000 --- a/src/color/xyz.js +++ /dev/null @@ -1,7 +0,0 @@ -function d3_xyz_lab(x) { - return x > 0.008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; -} - -function d3_xyz_rgb(r) { - return Math.round(255 * (r <= 0.00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - 0.055)); -} diff --git a/src/compat/date.js b/src/compat/date.js deleted file mode 100644 index e682d4cb8099fa..00000000000000 --- a/src/compat/date.js +++ /dev/null @@ -1,3 +0,0 @@ -if (!Date.now) Date.now = function() { - return +new Date; -}; diff --git a/src/compat/index.js b/src/compat/index.js deleted file mode 100644 index 25241cd9790dbf..00000000000000 --- a/src/compat/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import "date"; -import "style"; diff --git a/src/compat/style.js b/src/compat/style.js deleted file mode 100644 index 6d43c2ae429152..00000000000000 --- a/src/compat/style.js +++ /dev/null @@ -1,20 +0,0 @@ -import "../core/document"; - -try { - d3_document.createElement("div").style.setProperty("opacity", 0, ""); -} catch (error) { - var d3_element_prototype = d3_window.Element.prototype, - d3_element_setAttribute = d3_element_prototype.setAttribute, - d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, - d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, - d3_style_setProperty = d3_style_prototype.setProperty; - d3_element_prototype.setAttribute = function(name, value) { - d3_element_setAttribute.call(this, name, value + ""); - }; - d3_element_prototype.setAttributeNS = function(space, local, value) { - d3_element_setAttributeNS.call(this, space, local, value + ""); - }; - d3_style_prototype.setProperty = function(name, value, priority) { - d3_style_setProperty.call(this, name, value + "", priority); - }; -} diff --git a/src/core/array.js b/src/core/array.js deleted file mode 100644 index cb4fd3661b765a..00000000000000 --- a/src/core/array.js +++ /dev/null @@ -1,2 +0,0 @@ -var d3_arraySlice = [].slice, - d3_array = function(list) { return d3_arraySlice.call(list); }; // conversion for NodeLists diff --git a/src/core/class.js b/src/core/class.js deleted file mode 100644 index ca0fab7f30f4a2..00000000000000 --- a/src/core/class.js +++ /dev/null @@ -1,12 +0,0 @@ -function d3_class(ctor, properties) { - try { - for (var key in properties) { - Object.defineProperty(ctor.prototype, key, { - value: properties[key], - enumerable: false - }); - } - } catch (e) { - ctor.prototype = properties; - } -} diff --git a/src/core/document.js b/src/core/document.js deleted file mode 100644 index a9aff637dea32f..00000000000000 --- a/src/core/document.js +++ /dev/null @@ -1,16 +0,0 @@ -import "array"; - -var d3_document = document, - d3_documentElement = d3_document.documentElement, - d3_window = window; - -// Redefine d3_array if the browser doesn’t support slice-based conversion. -try { - d3_array(d3_documentElement.childNodes)[0].nodeType; -} catch(e) { - d3_array = function(list) { - var i = list.length, array = new Array(i); - while (i--) array[i] = list[i]; - return array; - }; -} diff --git a/src/core/functor.js b/src/core/functor.js deleted file mode 100644 index f8b1bf7cbbd525..00000000000000 --- a/src/core/functor.js +++ /dev/null @@ -1,5 +0,0 @@ -function d3_functor(v) { - return typeof v === "function" ? v : function() { return v; }; -} - -d3.functor = d3_functor; diff --git a/src/core/identity.js b/src/core/identity.js deleted file mode 100644 index 73893f86231a56..00000000000000 --- a/src/core/identity.js +++ /dev/null @@ -1,3 +0,0 @@ -function d3_identity(d) { - return d; -} diff --git a/src/core/index.js b/src/core/index.js deleted file mode 100644 index f6d233e0af9358..00000000000000 --- a/src/core/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import "functor"; -import "ns"; -import "rebind"; diff --git a/src/core/noop.js b/src/core/noop.js deleted file mode 100644 index 35f91d114d1b3e..00000000000000 --- a/src/core/noop.js +++ /dev/null @@ -1 +0,0 @@ -function d3_noop() {} diff --git a/src/core/ns.js b/src/core/ns.js deleted file mode 100644 index e23a653ba4918b..00000000000000 --- a/src/core/ns.js +++ /dev/null @@ -1,22 +0,0 @@ -var d3_nsPrefix = { - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" -}; - -d3.ns = { - prefix: d3_nsPrefix, - qualify: function(name) { - var i = name.indexOf(":"), - prefix = name; - if (i >= 0) { - prefix = name.substring(0, i); - name = name.substring(i + 1); - } - return d3_nsPrefix.hasOwnProperty(prefix) - ? {space: d3_nsPrefix[prefix], local: name} - : name; - } -}; diff --git a/src/core/rebind.js b/src/core/rebind.js deleted file mode 100644 index d61184646eee4d..00000000000000 --- a/src/core/rebind.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copies a variable number of methods from source to target. -d3.rebind = function(target, source) { - var i = 1, n = arguments.length, method; - while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); - return target; -}; - -// Method is assumed to be a standard D3 getter-setter: -// If passed with no arguments, gets the value. -// If passed with arguments, sets the value and returns the target. -function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return value === source ? target : value; - }; -} diff --git a/src/core/source.js b/src/core/source.js deleted file mode 100644 index f56f50138f1b12..00000000000000 --- a/src/core/source.js +++ /dev/null @@ -1,3 +0,0 @@ -function d3_source(d) { - return d.source; -} diff --git a/src/core/subclass.js b/src/core/subclass.js deleted file mode 100644 index ea8dc856cda0b4..00000000000000 --- a/src/core/subclass.js +++ /dev/null @@ -1,11 +0,0 @@ -var d3_subclass = {}.__proto__? - -// Until ECMAScript supports array subclassing, prototype injection works well. -function(object, prototype) { - object.__proto__ = prototype; -}: - -// And if your browser doesn't support __proto__, we'll use direct extension. -function(object, prototype) { - for (var property in prototype) object[property] = prototype[property]; -}; diff --git a/src/core/target.js b/src/core/target.js deleted file mode 100644 index 766ba7ee21267d..00000000000000 --- a/src/core/target.js +++ /dev/null @@ -1,3 +0,0 @@ -function d3_target(d) { - return d.target; -} diff --git a/src/core/true.js b/src/core/true.js deleted file mode 100644 index 0900faf20833ce..00000000000000 --- a/src/core/true.js +++ /dev/null @@ -1,3 +0,0 @@ -function d3_true() { - return true; -} diff --git a/src/core/vendor.js b/src/core/vendor.js deleted file mode 100644 index f4dcf39783b4f6..00000000000000 --- a/src/core/vendor.js +++ /dev/null @@ -1,12 +0,0 @@ -import "document"; - -function d3_vendorSymbol(object, name) { - if (name in object) return name; - name = name.charAt(0).toUpperCase() + name.substring(1); - for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { - var prefixName = d3_vendorPrefixes[i] + name; - if (prefixName in object) return prefixName; - } -} - -var d3_vendorPrefixes = ["webkit", "ms", "moz", "Moz", "o", "O"]; diff --git a/src/d3.js b/src/d3.js deleted file mode 100644 index d0ad7385077cad..00000000000000 --- a/src/d3.js +++ /dev/null @@ -1,23 +0,0 @@ -import "start"; -import "compat/"; - -import "arrays/"; -import "behavior/"; -import "color/"; -import "core/"; -import "dsv/"; -import "event/"; -import "format/"; -import "geo/"; -import "geom/"; -import "interpolate/"; -import "layout/"; -import "math/"; -import "scale/"; -import "selection/"; -import "svg/"; -import "time/"; -import "transition/"; -import "xhr/"; - -import "end"; diff --git a/src/dsv/csv.js b/src/dsv/csv.js deleted file mode 100644 index 2b6d94f68376d7..00000000000000 --- a/src/dsv/csv.js +++ /dev/null @@ -1,3 +0,0 @@ -import "dsv"; - -d3.csv = d3.dsv(",", "text/csv"); diff --git a/src/dsv/dsv.js b/src/dsv/dsv.js deleted file mode 100644 index 8c8f469c8f5e16..00000000000000 --- a/src/dsv/dsv.js +++ /dev/null @@ -1,136 +0,0 @@ -import "../arrays/set"; -import "../xhr/xhr"; - -d3.dsv = function(delimiter, mimeType) { - var reFormat = new RegExp("[\"" + delimiter + "\n]"), - delimiterCode = delimiter.charCodeAt(0); - - function dsv(url, row, callback) { - if (arguments.length < 3) callback = row, row = null; - var xhr = d3.xhr(url, mimeType, callback); - - xhr.row = function(_) { - return arguments.length - ? xhr.response((row = _) == null ? response : typedResponse(_)) - : row; - }; - - return xhr.row(row); - } - - function response(request) { - return dsv.parse(request.responseText); - } - - function typedResponse(f) { - return function(request) { - return dsv.parse(request.responseText, f); - }; - } - - dsv.parse = function(text, f) { - var o; - return dsv.parseRows(text, function(row, i) { - if (o) return o(row, i - 1); - var a = new Function("d", "return {" + row.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); - o = f ? function(row, i) { return f(a(row), i); } : a; - }); - }; - - dsv.parseRows = function(text, f) { - var EOL = {}, // sentinel value for end-of-line - EOF = {}, // sentinel value for end-of-file - rows = [], // output rows - N = text.length, - I = 0, // current character index - n = 0, // the current line number - t, // the current token - eol; // is the current token followed by EOL? - - function token() { - if (I >= N) return EOF; // special case: end of file - if (eol) return eol = false, EOL; // special case: end of line - - // special case: quotes - var j = I; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - var c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.substring(j + 1, i).replace(/""/g, "\""); - } - - // common case: find next delimiter or newline - while (I < N) { - var c = text.charCodeAt(I++), k = 1; - if (c === 10) eol = true; // \n - else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n - else if (c !== delimiterCode) continue; - return text.substring(j, I - k); - } - - // special case: last token before EOF - return text.substring(j); - } - - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && !(a = f(a, n++))) continue; - rows.push(a); - } - - return rows; - }; - - dsv.format = function(rows) { - if (Array.isArray(rows[0])) return dsv.formatRows(rows); // deprecated; use formatRows - var fieldSet = new d3_Set, fields = []; - - // Compute unique fields in order of discovery. - rows.forEach(function(row) { - for (var field in row) { - if (!fieldSet.has(field)) { - fields.push(fieldSet.add(field)); - } - } - }); - - return [fields.map(formatValue).join(delimiter)].concat(rows.map(function(row) { - return fields.map(function(field) { - return formatValue(row[field]); - }).join(delimiter); - })).join("\n"); - }; - - dsv.formatRows = function(rows) { - return rows.map(formatRow).join("\n"); - }; - - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - - function formatValue(text) { - return reFormat.test(text) ? "\"" + text.replace(/\"/g, "\"\"") + "\"" : text; - } - - return dsv; -}; diff --git a/src/dsv/index.js b/src/dsv/index.js deleted file mode 100644 index b92fc3cc14e90e..00000000000000 --- a/src/dsv/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import "dsv"; -import "csv"; -import "tsv"; diff --git a/src/dsv/tsv.js b/src/dsv/tsv.js deleted file mode 100644 index 1783744e2ab091..00000000000000 --- a/src/dsv/tsv.js +++ /dev/null @@ -1,3 +0,0 @@ -import "dsv"; - -d3.tsv = d3.dsv("\t", "text/tab-separated-values"); diff --git a/src/end.js b/src/end.js deleted file mode 100644 index c76f8bd5e0bd47..00000000000000 --- a/src/end.js +++ /dev/null @@ -1,2 +0,0 @@ - return d3; -})(); diff --git a/src/event/dispatch.js b/src/event/dispatch.js deleted file mode 100644 index 86efe7f213d450..00000000000000 --- a/src/event/dispatch.js +++ /dev/null @@ -1,69 +0,0 @@ -import "../arrays/map"; - -d3.dispatch = function() { - var dispatch = new d3_dispatch, - i = -1, - n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - return dispatch; -}; - -function d3_dispatch() {} - -d3_dispatch.prototype.on = function(type, listener) { - var i = type.indexOf("."), - name = ""; - - // Extract optional namespace, e.g., "click.foo" - if (i >= 0) { - name = type.substring(i + 1); - type = type.substring(0, i); - } - - if (type) return arguments.length < 2 - ? this[type].on(name) - : this[type].on(name, listener); - - if (arguments.length === 2) { - if (listener == null) for (type in this) { - if (this.hasOwnProperty(type)) this[type].on(name, null); - } - return this; - } -}; - -function d3_dispatch_event(dispatch) { - var listeners = [], - listenerByName = new d3_Map; - - function event() { - var z = listeners, // defensive reference - i = -1, - n = z.length, - l; - while (++i < n) if (l = z[i].on) l.apply(this, arguments); - return dispatch; - } - - event.on = function(name, listener) { - var l = listenerByName.get(name), - i; - - // return the current listener, if any - if (arguments.length < 2) return l && l.on; - - // remove the old listener, if any (with copy-on-write) - if (l) { - l.on = null; - listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); - listenerByName.remove(name); - } - - // add the new listener, if any - if (listener) listeners.push(listenerByName.set(name, {on: listener})); - - return dispatch; - }; - - return event; -} diff --git a/src/event/drag.js b/src/event/drag.js deleted file mode 100644 index f271704cdbe3f9..00000000000000 --- a/src/event/drag.js +++ /dev/null @@ -1,27 +0,0 @@ -import "../core/document"; -import "../core/vendor"; -import "../selection/on"; - -var d3_event_dragSelect = d3_vendorSymbol(d3_documentElement.style, "userSelect"), - d3_event_dragId = 0; - -function d3_event_dragSuppress() { - var name = ".dragsuppress-" + ++d3_event_dragId, - touchmove = "touchmove" + name, - selectstart = "selectstart" + name, - dragstart = "dragstart" + name, - click = "click" + name, - w = d3.select(d3_window).on(touchmove, d3_eventPreventDefault).on(selectstart, d3_eventPreventDefault).on(dragstart, d3_eventPreventDefault), - style = d3_documentElement.style, - select = style[d3_event_dragSelect]; - style[d3_event_dragSelect] = "none"; - return function(suppressClick) { - w.on(name, null); - style[d3_event_dragSelect] = select; - if (suppressClick) { // suppress the next click, but only if it’s immediate - function off() { w.on(click, null); } - w.on(click, function() { d3_eventPreventDefault(); off(); }, true); - setTimeout(off, 0); - } - }; -} diff --git a/src/event/event.js b/src/event/event.js deleted file mode 100644 index 71e676ee9058c9..00000000000000 --- a/src/event/event.js +++ /dev/null @@ -1,50 +0,0 @@ -import "dispatch"; - -d3.event = null; - -function d3_eventPreventDefault() { - d3.event.preventDefault(); -} - -function d3_eventSource() { - var e = d3.event, s; - while (s = e.sourceEvent) e = s; - return e; -} - -// Like d3.dispatch, but for custom events abstracting native UI events. These -// events have a target component (such as a brush), a target element (such as -// the svg:g element containing the brush) and the standard arguments `d` (the -// target element's data) and `i` (the selection index of the target element). -function d3_eventDispatch(target) { - var dispatch = new d3_dispatch, - i = 0, - n = arguments.length; - - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - - // Creates a dispatch context for the specified `thiz` (typically, the target - // DOM element that received the source event) and `argumentz` (typically, the - // data `d` and index `i` of the target element). The returned function can be - // used to dispatch an event to any registered listeners; the function takes a - // single argument as input, being the event to dispatch. The event must have - // a "type" attribute which corresponds to a type registered in the - // constructor. This context will automatically populate the "sourceEvent" and - // "target" attributes of the event, as well as setting the `d3.event` global - // for the duration of the notification. - dispatch.of = function(thiz, argumentz) { - return function(e1) { - try { - var e0 = - e1.sourceEvent = d3.event; - e1.target = target; - d3.event = e1; - dispatch[e1.type].apply(thiz, argumentz); - } finally { - d3.event = e0; - } - }; - }; - - return dispatch; -} diff --git a/src/event/index.js b/src/event/index.js deleted file mode 100644 index ac2f7f92db6da4..00000000000000 --- a/src/event/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import "dispatch"; -import "event"; -import "mouse"; -import "touches"; -import "timer"; diff --git a/src/event/mouse.js b/src/event/mouse.js deleted file mode 100644 index 1f31e133706836..00000000000000 --- a/src/event/mouse.js +++ /dev/null @@ -1,35 +0,0 @@ -import "../core/document"; - -d3.mouse = function(container) { - return d3_mousePoint(container, d3_eventSource()); -}; - -// https://bugs.webkit.org/show_bug.cgi?id=44083 -var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0; - -function d3_mousePoint(container, e) { - if (e.changedTouches) e = e.changedTouches[0]; - var svg = container.ownerSVGElement || container; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) { - svg = d3.select("body").append("svg").style({ - position: "absolute", - top: 0, - left: 0, - margin: 0, - padding: 0, - border: "none" - }, "important"); - var ctm = svg[0][0].getScreenCTM(); - d3_mouse_bug44083 = !(ctm.f || ctm.e); - svg.remove(); - } - if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; - else point.x = e.clientX, point.y = e.clientY; - point = point.matrixTransform(container.getScreenCTM().inverse()); - return [point.x, point.y]; - } - var rect = container.getBoundingClientRect(); - return [e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop]; -}; diff --git a/src/event/timer.js b/src/event/timer.js deleted file mode 100644 index 8e6976b811cadd..00000000000000 --- a/src/event/timer.js +++ /dev/null @@ -1,85 +0,0 @@ -import "../core/document"; -import "../core/vendor"; - -var d3_timer_queueHead, - d3_timer_queueTail, - d3_timer_interval, // is an interval (or frame) active? - d3_timer_timeout, // is a timeout active? - d3_timer_active, // active timer object - d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) { setTimeout(callback, 17); }; - -// The timer will continue to fire until callback returns true. -d3.timer = function(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - - // Add the callback to the tail of the queue. - var time = then + delay, timer = {callback: callback, time: time, next: null}; - if (d3_timer_queueTail) d3_timer_queueTail.next = timer; - else d3_timer_queueHead = timer; - d3_timer_queueTail = timer; - - // Start animatin'! - if (!d3_timer_interval) { - d3_timer_timeout = clearTimeout(d3_timer_timeout); - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } -}; - -function d3_timer_step() { - var now = d3_timer_mark(), - delay = d3_timer_sweep() - now; - if (delay > 24) { - if (isFinite(delay)) { - clearTimeout(d3_timer_timeout); - d3_timer_timeout = setTimeout(d3_timer_step, delay); - } - d3_timer_interval = 0; - } else { - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } -} - -d3.timer.flush = function() { - d3_timer_mark(); - d3_timer_sweep(); -}; - -function d3_timer_replace(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - d3_timer_active.callback = callback; - d3_timer_active.time = then + delay; -} - -function d3_timer_mark() { - var now = Date.now(); - d3_timer_active = d3_timer_queueHead; - while (d3_timer_active) { - if (now >= d3_timer_active.time) d3_timer_active.flush = d3_timer_active.callback(now - d3_timer_active.time); - d3_timer_active = d3_timer_active.next; - } - return now; -} - -// Flush after callbacks to avoid concurrent queue modification. -// Returns the time of the earliest active timer, post-sweep. -function d3_timer_sweep() { - var t0, - t1 = d3_timer_queueHead, - time = Infinity; - while (t1) { - if (t1.flush) { - t1 = t0 ? t0.next = t1.next : d3_timer_queueHead = t1.next; - } else { - if (t1.time < time) time = t1.time; - t1 = (t0 = t1).next; - } - } - d3_timer_queueTail = t0; - return time; -} diff --git a/src/event/touches.js b/src/event/touches.js deleted file mode 100644 index a7cbaa5f91d29e..00000000000000 --- a/src/event/touches.js +++ /dev/null @@ -1,12 +0,0 @@ -import "../core/array"; -import "event"; -import "mouse"; - -d3.touches = function(container, touches) { - if (arguments.length < 2) touches = d3_eventSource().touches; - return touches ? d3_array(touches).map(function(touch) { - var point = d3_mousePoint(container, touch); - point.identifier = touch.identifier; - return point; - }) : []; -}; diff --git a/src/format/collapse.js b/src/format/collapse.js deleted file mode 100644 index 08adc3a69e755b..00000000000000 --- a/src/format/collapse.js +++ /dev/null @@ -1,3 +0,0 @@ -function d3_collapse(s) { - return s.trim().replace(/\s+/g, " "); -} diff --git a/src/format/format-locale.js b/src/format/format-locale.js deleted file mode 100644 index 0cee8d056d6116..00000000000000 --- a/src/format/format-locale.js +++ /dev/null @@ -1,4 +0,0 @@ -var d3_format_decimalPoint = {decimal_point}, - d3_format_thousandsSeparator = {thousands_sep}, - d3_format_grouping = {grouping}, - d3_format_currencySymbol = {currency_symbol}; diff --git a/src/format/format-localized.js b/src/format/format-localized.js deleted file mode 100644 index b7e5e9abc8ea4b..00000000000000 --- a/src/format/format-localized.js +++ /dev/null @@ -1,5 +0,0 @@ -var d3_format_decimalPoint = ".", - d3_format_thousandsSeparator = ",", - d3_format_grouping = [3, 3], - d3_format_currencySymbol = "$"; - diff --git a/src/format/format.js b/src/format/format.js deleted file mode 100644 index 7e708e22ab1d0f..00000000000000 --- a/src/format/format.js +++ /dev/null @@ -1,144 +0,0 @@ -import "../arrays/map"; -import "../core/identity"; -import "format-localized"; -import "formatPrefix"; -import "round"; - -d3.format = function(specifier) { - var match = d3_format_re.exec(specifier), - fill = match[1] || " ", - align = match[2] || ">", - sign = match[3] || "", - symbol = match[4] || "", - zfill = match[5], - width = +match[6], - comma = match[7], - precision = match[8], - type = match[9], - scale = 1, - suffix = "", - integer = false; - - if (precision) precision = +precision.substring(1); - - if (zfill || fill === "0" && align === "=") { - zfill = fill = "0"; - align = "="; - if (comma) width -= Math.floor((width - 1) / 4); - } - - switch (type) { - case "n": comma = true; type = "g"; break; - case "%": scale = 100; suffix = "%"; type = "f"; break; - case "p": scale = 100; suffix = "%"; type = "r"; break; - case "b": - case "o": - case "x": - case "X": if (symbol === "#") symbol = "0" + type.toLowerCase(); - case "c": - case "d": integer = true; precision = 0; break; - case "s": scale = -1; type = "r"; break; - } - - if (symbol === "#") symbol = ""; - else if (symbol === "$") symbol = d3_format_currencySymbol; - - // If no precision is specified for r, fallback to general notation. - if (type == "r" && !precision) type = "g"; - - // Ensure that the requested precision is in the supported range. - if (precision != null) { - if (type == "g") precision = Math.max(1, Math.min(21, precision)); - else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); - } - - type = d3_format_types.get(type) || d3_format_typeDefault; - - var zcomma = zfill && comma; - - return function(value) { - - // Return the empty string for floats formatted as ints. - if (integer && (value % 1)) return ""; - - // Convert negative to positive, and record the sign prefix. - var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; - - // Apply the scale, computing it from the value's exponent for si format. - if (scale < 0) { - var prefix = d3.formatPrefix(value, precision); - value = prefix.scale(value); - suffix = prefix.symbol; - } else { - value *= scale; - } - - // Convert to the desired precision. - value = type(value, precision); - - // Break the value into the integer part (before) and decimal part (after). - var i = value.lastIndexOf("."), - before = i < 0 ? value : value.substring(0, i), - after = i < 0 ? "" : d3_format_decimalPoint + value.substring(i + 1); - - // If the fill character is not "0", grouping is applied before padding. - if (!zfill && comma) before = d3_format_group(before); - - var length = symbol.length + before.length + after.length + (zcomma ? 0 : negative.length), - padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; - - // If the fill character is "0", grouping is applied after padding. - if (zcomma) before = d3_format_group(padding + before); - - // Apply symbol as prefix. TODO allow suffix symbols - negative += symbol; - - // Rejoin integer and decimal parts. - value = before + after; - - return (align === "<" ? negative + value + padding - : align === ">" ? padding + negative + value - : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) - : negative + (zcomma ? value : padding + value)) + suffix; - }; -}; - -// [[fill]align][sign][symbol][0][width][,][.precision][type] -var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; - -var d3_format_types = d3.map({ - b: function(x) { return x.toString(2); }, - c: function(x) { return String.fromCharCode(x); }, - o: function(x) { return x.toString(8); }, - x: function(x) { return x.toString(16); }, - X: function(x) { return x.toString(16).toUpperCase(); }, - g: function(x, p) { return x.toPrecision(p); }, - e: function(x, p) { return x.toExponential(p); }, - f: function(x, p) { return x.toFixed(p); }, - r: function(x, p) { return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); } -}); - -function d3_format_precision(x, p) { - return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); -} - -function d3_format_typeDefault(x) { - return x + ""; -} - -// Apply comma grouping for thousands. -var d3_format_group = d3_identity; -if (d3_format_grouping) { - var d3_format_groupingLength = d3_format_grouping.length; - d3_format_group = function(value) { - var i = value.length, - t = [], - j = 0, - g = d3_format_grouping[0]; - while (i > 0 && g > 0) { - t.push(value.substring(i -= g, i + g)); - g = d3_format_grouping[j = (j + 1) % d3_format_groupingLength]; - } - return t.reverse().join(d3_format_thousandsSeparator); - }; -} diff --git a/src/format/formatPrefix.js b/src/format/formatPrefix.js deleted file mode 100644 index b86d90336b9c2a..00000000000000 --- a/src/format/formatPrefix.js +++ /dev/null @@ -1,22 +0,0 @@ -import "format"; - -var d3_formatPrefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"].map(d3_formatPrefix); - -d3.formatPrefix = function(value, precision) { - var i = 0; - if (value) { - if (value < 0) value *= -1; - if (precision) value = d3.round(value, d3_format_precision(value, precision)); - i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); - i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3)); - } - return d3_formatPrefixes[8 + i / 3]; -}; - -function d3_formatPrefix(d, i) { - var k = Math.pow(10, Math.abs(8 - i) * 3); - return { - scale: i > 8 ? function(d) { return d / k; } : function(d) { return d * k; }, - symbol: d - }; -} diff --git a/src/format/index.js b/src/format/index.js deleted file mode 100644 index 21d7e9de2b5804..00000000000000 --- a/src/format/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import "format"; -import "formatPrefix"; -import "requote"; -import "round"; diff --git a/src/format/requote.js b/src/format/requote.js deleted file mode 100644 index 99dbf15a7df497..00000000000000 --- a/src/format/requote.js +++ /dev/null @@ -1,5 +0,0 @@ -d3.requote = function(s) { - return s.replace(d3_requote_re, "\\$&"); -}; - -var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; diff --git a/src/format/round.js b/src/format/round.js deleted file mode 100644 index 44e9574295a465..00000000000000 --- a/src/format/round.js +++ /dev/null @@ -1,5 +0,0 @@ -d3.round = function(x, n) { - return n - ? Math.round(x * (n = Math.pow(10, n))) / n - : Math.round(x); -}; diff --git a/src/geo/albers-usa.js b/src/geo/albers-usa.js deleted file mode 100644 index bee8ed22f8a125..00000000000000 --- a/src/geo/albers-usa.js +++ /dev/null @@ -1,129 +0,0 @@ -import "albers"; -import "conic-equal-area"; -import "geo"; - -// A composite projection for the United States, configured by default for -// 960×500. Also works quite well at 960×600 with scale 1285. The set of -// standard parallels for each region comes from USGS, which is published here: -// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers -d3.geo.albersUsa = function() { - var lower48 = d3.geo.albers(); - - // EPSG:3338 - var alaska = d3.geo.conicEqualArea() - .rotate([154, 0]) - .center([-2, 58.5]) - .parallels([55, 65]); - - // ESRI:102007 - var hawaii = d3.geo.conicEqualArea() - .rotate([157, 0]) - .center([-3, 19.9]) - .parallels([8, 18]); - - var point, - pointStream = {point: function(x, y) { point = [x, y]; }}, - lower48Point, - alaskaPoint, - hawaiiPoint; - - function albersUsa(coordinates) { - var x = coordinates[0], y = coordinates[1]; - point = null; - (lower48Point(x, y), point) - || (alaskaPoint(x, y), point) - || hawaiiPoint(x, y); - return point; - } - - albersUsa.invert = function(coordinates) { - var k = lower48.scale(), - t = lower48.translate(), - x = (coordinates[0] - t[0]) / k, - y = (coordinates[1] - t[1]) / k; - return (y >= .120 && y < .234 && x >= -.425 && x < -.214 ? alaska - : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii - : lower48).invert(coordinates); - }; - - // A naïve multi-projection stream. - // The projections must have mutually exclusive clip regions on the sphere, - // as this will avoid emitting interleaving lines and polygons. - albersUsa.stream = function(stream) { - var lower48Stream = lower48.stream(stream), - alaskaStream = alaska.stream(stream), - hawaiiStream = hawaii.stream(stream); - return { - point: function(x, y) { - lower48Stream.point(x, y); - alaskaStream.point(x, y); - hawaiiStream.point(x, y); - }, - sphere: function() { - lower48Stream.sphere(); - alaskaStream.sphere(); - hawaiiStream.sphere(); - }, - lineStart: function() { - lower48Stream.lineStart(); - alaskaStream.lineStart(); - hawaiiStream.lineStart(); - }, - lineEnd: function() { - lower48Stream.lineEnd(); - alaskaStream.lineEnd(); - hawaiiStream.lineEnd(); - }, - polygonStart: function() { - lower48Stream.polygonStart(); - alaskaStream.polygonStart(); - hawaiiStream.polygonStart(); - }, - polygonEnd: function() { - lower48Stream.polygonEnd(); - alaskaStream.polygonEnd(); - hawaiiStream.polygonEnd(); - } - }; - }; - - albersUsa.precision = function(_) { - if (!arguments.length) return lower48.precision(); - lower48.precision(_); - alaska.precision(_); - hawaii.precision(_); - return albersUsa; - }; - - albersUsa.scale = function(_) { - if (!arguments.length) return lower48.scale(); - lower48.scale(_); - alaska.scale(_ * .35); - hawaii.scale(_); - return albersUsa.translate(lower48.translate()); - }; - - albersUsa.translate = function(_) { - if (!arguments.length) return lower48.translate(); - var k = lower48.scale(), x = +_[0], y = +_[1]; - - lower48Point = lower48 - .translate(_) - .clipExtent([[x - .455 * k, y - .238 * k], [x + .455 * k, y + .238 * k]]) - .stream(pointStream).point; - - alaskaPoint = alaska - .translate([x - .307 * k, y + .201 * k]) - .clipExtent([[x - .425 * k + ε, y + .120 * k + ε], [x - .214 * k - ε, y + .234 * k - ε]]) - .stream(pointStream).point; - - hawaiiPoint = hawaii - .translate([x - .205 * k, y + .212 * k]) - .clipExtent([[x - .214 * k + ε, y + .166 * k + ε], [x - .115 * k - ε, y + .234 * k - ε]]) - .stream(pointStream).point; - - return albersUsa; - }; - - return albersUsa.scale(1070); -}; diff --git a/src/geo/albers.js b/src/geo/albers.js deleted file mode 100644 index c1cde75b70519c..00000000000000 --- a/src/geo/albers.js +++ /dev/null @@ -1,11 +0,0 @@ -import "conic-equal-area"; -import "geo"; - -// ESRI:102003 -d3.geo.albers = function() { - return d3.geo.conicEqualArea() - .rotate([96, 0]) - .center([-.6, 38.7]) - .parallels([29.5, 45.5]) - .scale(1070); -}; diff --git a/src/geo/area.js b/src/geo/area.js deleted file mode 100644 index 2d7def0ec6fb91..00000000000000 --- a/src/geo/area.js +++ /dev/null @@ -1,67 +0,0 @@ -import "../core/noop"; -import "../math/adder"; -import "../math/trigonometry"; -import "geo"; -import "stream"; - -d3.geo.area = function(object) { - d3_geo_areaSum = 0; - d3.geo.stream(object, d3_geo_area); - return d3_geo_areaSum; -}; - -var d3_geo_areaSum, - d3_geo_areaRingSum = new d3_adder; - -var d3_geo_area = { - sphere: function() { d3_geo_areaSum += 4 * π; }, - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - - // Only count area for polygon rings. - polygonStart: function() { - d3_geo_areaRingSum.reset(); - d3_geo_area.lineStart = d3_geo_areaRingStart; - }, - polygonEnd: function() { - var area = 2 * d3_geo_areaRingSum; - d3_geo_areaSum += area < 0 ? 4 * π + area : area; - d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; - } -}; - -function d3_geo_areaRingStart() { - var λ00, φ00, λ0, cosφ0, sinφ0; // start point and previous point - - // For the first point, … - d3_geo_area.point = function(λ, φ) { - d3_geo_area.point = nextPoint; - λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), sinφ0 = Math.sin(φ); - }; - - // For subsequent points, … - function nextPoint(λ, φ) { - λ *= d3_radians; - φ = φ * d3_radians / 2 + π / 4; // half the angular distance from south pole - - // Spherical excess E for a spherical triangle with vertices: south pole, - // previous point, current point. Uses a formula derived from Cagnoli’s - // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2). - var dλ = λ - λ0, - cosφ = Math.cos(φ), - sinφ = Math.sin(φ), - k = sinφ0 * sinφ, - u = cosφ0 * cosφ + k * Math.cos(dλ), - v = k * Math.sin(dλ); - d3_geo_areaRingSum.add(Math.atan2(v, u)); - - // Advance the previous points. - λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; - } - - // For the last point, return to the start. - d3_geo_area.lineEnd = function() { - nextPoint(λ00, φ00); - }; -} diff --git a/src/geo/azimuthal-equal-area.js b/src/geo/azimuthal-equal-area.js deleted file mode 100644 index 91bdcd66c42af0..00000000000000 --- a/src/geo/azimuthal-equal-area.js +++ /dev/null @@ -1,12 +0,0 @@ -import "azimuthal"; -import "geo"; -import "projection"; - -var d3_geo_azimuthalEqualArea = d3_geo_azimuthal( - function(cosλcosφ) { return Math.sqrt(2 / (1 + cosλcosφ)); }, - function(ρ) { return 2 * Math.asin(ρ / 2); } -); - -(d3.geo.azimuthalEqualArea = function() { - return d3_geo_projection(d3_geo_azimuthalEqualArea); -}).raw = d3_geo_azimuthalEqualArea; diff --git a/src/geo/azimuthal-equidistant.js b/src/geo/azimuthal-equidistant.js deleted file mode 100644 index 80b14a941603e8..00000000000000 --- a/src/geo/azimuthal-equidistant.js +++ /dev/null @@ -1,13 +0,0 @@ -import "../core/identity"; -import "azimuthal"; -import "geo"; -import "projection"; - -var d3_geo_azimuthalEquidistant = d3_geo_azimuthal( - function(cosλcosφ) { var c = Math.acos(cosλcosφ); return c && c / Math.sin(c); }, - d3_identity -); - -(d3.geo.azimuthalEquidistant = function() { - return d3_geo_projection(d3_geo_azimuthalEquidistant); -}).raw = d3_geo_azimuthalEquidistant; diff --git a/src/geo/azimuthal.js b/src/geo/azimuthal.js deleted file mode 100644 index 5c0d9f5a9d0f81..00000000000000 --- a/src/geo/azimuthal.js +++ /dev/null @@ -1,25 +0,0 @@ -// Abstract azimuthal projection. -function d3_geo_azimuthal(scale, angle) { - function azimuthal(λ, φ) { - var cosλ = Math.cos(λ), - cosφ = Math.cos(φ), - k = scale(cosλ * cosφ); - return [ - k * cosφ * Math.sin(λ), - k * Math.sin(φ) - ]; - } - - azimuthal.invert = function(x, y) { - var ρ = Math.sqrt(x * x + y * y), - c = angle(ρ), - sinc = Math.sin(c), - cosc = Math.cos(c); - return [ - Math.atan2(x * sinc, ρ * cosc), - Math.asin(ρ && y * sinc / ρ) - ]; - }; - - return azimuthal; -} diff --git a/src/geo/bounds.js b/src/geo/bounds.js deleted file mode 100644 index 242389d54d6851..00000000000000 --- a/src/geo/bounds.js +++ /dev/null @@ -1,169 +0,0 @@ -import "../core/identity"; -import "../core/noop"; -import "geo"; -import "stream"; -import "area"; -import "cartesian"; -import "spherical"; - -d3.geo.bounds = (function() { - var λ0, φ0, λ1, φ1, // bounds - λ_, // previous λ-coordinate - λ__, φ__, // first point - p0, // previous 3D point - dλSum, - ranges, - range; - - var bound = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - - polygonStart: function() { - bound.point = ringPoint; - bound.lineStart = ringStart; - bound.lineEnd = ringEnd; - dλSum = 0; - d3_geo_area.polygonStart(); - }, - polygonEnd: function() { - d3_geo_area.polygonEnd(); - bound.point = point; - bound.lineStart = lineStart; - bound.lineEnd = lineEnd; - if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); - else if (dλSum > ε) φ1 = 90; - else if (dλSum < -ε) φ0 = -90; - range[0] = λ0, range[1] = λ1; - } - }; - - function point(λ, φ) { - ranges.push(range = [λ0 = λ, λ1 = λ]); - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - - function linePoint(λ, φ) { - var p = d3_geo_cartesian([λ * d3_radians, φ * d3_radians]); - if (p0) { - var normal = d3_geo_cartesianCross(p0, p), - equatorial = [normal[1], -normal[0], 0], - inflection = d3_geo_cartesianCross(equatorial, normal); - d3_geo_cartesianNormalize(inflection); - inflection = d3_geo_spherical(inflection); - var dλ = λ - λ_, - s = dλ > 0 ? 1 : -1, - λi = inflection[0] * d3_degrees * s, - antimeridian = Math.abs(dλ) > 180; - if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = inflection[1] * d3_degrees; - if (φi > φ1) φ1 = φi; - } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = -inflection[1] * d3_degrees; - if (φi < φ0) φ0 = φi; - } else { - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - if (antimeridian) { - if (λ < λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } else { - if (λ1 >= λ0) { - if (λ < λ0) λ0 = λ; - if (λ > λ1) λ1 = λ; - } else { - if (λ > λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } - } - } else { - point(λ, φ); - } - p0 = p, λ_ = λ; - } - - function lineStart() { bound.point = linePoint; } - function lineEnd() { - range[0] = λ0, range[1] = λ1; - bound.point = point; - p0 = null; - } - - function ringPoint(λ, φ) { - if (p0) { - var dλ = λ - λ_; - dλSum += Math.abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; - } else λ__ = λ, φ__ = φ; - d3_geo_area.point(λ, φ); - linePoint(λ, φ); - } - - function ringStart() { - d3_geo_area.lineStart(); - } - - function ringEnd() { - ringPoint(λ__, φ__); - d3_geo_area.lineEnd(); - if (Math.abs(dλSum) > ε) λ0 = -(λ1 = 180); - range[0] = λ0, range[1] = λ1; - p0 = null; - } - - // Finds the left-right distance between two longitudes. - // This is almost the same as (λ1 - λ0 + 360°) % 360°, except that we want - // the distance between ±180° to be 360°. - function angle(λ0, λ1) { return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; } - - function compareRanges(a, b) { return a[0] - b[0]; } - - function withinRange(x, range) { - return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; - } - - return function(feature) { - φ1 = λ1 = -(λ0 = φ0 = Infinity); - ranges = []; - - d3.geo.stream(feature, bound); - - var n = ranges.length; - if (n) { - // First, sort ranges by their minimum longitudes. - ranges.sort(compareRanges); - - // Then, merge any ranges that overlap. - for (var i = 1, a = ranges[0], b, merged = [a]; i < n; ++i) { - b = ranges[i]; - if (withinRange(b[0], a) || withinRange(b[1], a)) { - if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; - if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; - } else { - merged.push(a = b); - } - } - - // Finally, find the largest gap between the merged ranges. - // The final bounding box will be the inverse of this gap. - var best = -Infinity, dλ; - for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { - b = merged[i]; - if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; - } - } - ranges = range = null; - - return λ0 === Infinity || φ0 === Infinity - ? [[NaN, NaN], [NaN, NaN]] - : [[λ0, φ0], [λ1, φ1]]; - }; -})(); diff --git a/src/geo/cartesian.js b/src/geo/cartesian.js deleted file mode 100644 index f365a3dd0814e2..00000000000000 --- a/src/geo/cartesian.js +++ /dev/null @@ -1,47 +0,0 @@ -// TODO -// cross and scale return new vectors, -// whereas add and normalize operate in-place - -function d3_geo_cartesian(spherical) { - var λ = spherical[0], - φ = spherical[1], - cosφ = Math.cos(φ); - return [ - cosφ * Math.cos(λ), - cosφ * Math.sin(λ), - Math.sin(φ) - ]; -} - -function d3_geo_cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; -} - -function d3_geo_cartesianCross(a, b) { - return [ - a[1] * b[2] - a[2] * b[1], - a[2] * b[0] - a[0] * b[2], - a[0] * b[1] - a[1] * b[0] - ]; -} - -function d3_geo_cartesianAdd(a, b) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; -} - -function d3_geo_cartesianScale(vector, k) { - return [ - vector[0] * k, - vector[1] * k, - vector[2] * k - ]; -} - -function d3_geo_cartesianNormalize(d) { - var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l; - d[1] /= l; - d[2] /= l; -} diff --git a/src/geo/centroid.js b/src/geo/centroid.js deleted file mode 100644 index b764e9fd81f1ef..00000000000000 --- a/src/geo/centroid.js +++ /dev/null @@ -1,149 +0,0 @@ -import "../core/noop"; -import "../math/trigonometry"; -import "geo"; -import "stream"; - -d3.geo.centroid = function(object) { - d3_geo_centroidW0 = d3_geo_centroidW1 = - d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = - d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = - d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, d3_geo_centroid); - - var x = d3_geo_centroidX2, - y = d3_geo_centroidY2, - z = d3_geo_centroidZ2, - m = x * x + y * y + z * z; - - // If the area-weighted centroid is undefined, fall back to length-weighted centroid. - if (m < ε2) { - x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; - // If the feature has zero length, fall back to arithmetic mean of point vectors. - if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; - m = x * x + y * y + z * z; - // If the feature still has an undefined centroid, then return. - if (m < ε2) return [NaN, NaN]; - } - - return [Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees]; -}; - -var d3_geo_centroidW0, - d3_geo_centroidW1, - d3_geo_centroidX0, - d3_geo_centroidY0, - d3_geo_centroidZ0, - d3_geo_centroidX1, - d3_geo_centroidY1, - d3_geo_centroidZ1, - d3_geo_centroidX2, - d3_geo_centroidY2, - d3_geo_centroidZ2; - -var d3_geo_centroid = { - sphere: d3_noop, - point: d3_geo_centroidPoint, - lineStart: d3_geo_centroidLineStart, - lineEnd: d3_geo_centroidLineEnd, - polygonStart: function() { - d3_geo_centroid.lineStart = d3_geo_centroidRingStart; - }, - polygonEnd: function() { - d3_geo_centroid.lineStart = d3_geo_centroidLineStart; - } -}; - -// Arithmetic mean of Cartesian vectors. -function d3_geo_centroidPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); -} - -function d3_geo_centroidPointXYZ(x, y, z) { - ++d3_geo_centroidW0; - d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; - d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; - d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; -} - -function d3_geo_centroidLineStart() { - var x0, y0, z0; // previous point - - d3_geo_centroid.point = function(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroid.point = nextPoint; - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), - x = cosφ * Math.cos(λ), - y = cosφ * Math.sin(λ), - z = Math.sin(φ), - w = Math.atan2( - Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), - x0 * x + y0 * y + z0 * z); - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } -} - -function d3_geo_centroidLineEnd() { - d3_geo_centroid.point = d3_geo_centroidPoint; -} - -// See J. E. Brock, The Inertia Tensor for a Spherical Triangle, -// J. Applied Mechanics 42, 239 (1975). -function d3_geo_centroidRingStart() { - var λ00, φ00, // first point - x0, y0, z0; // previous point - - d3_geo_centroid.point = function(λ, φ) { - λ00 = λ, φ00 = φ; - d3_geo_centroid.point = nextPoint; - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - - d3_geo_centroid.lineEnd = function() { - nextPoint(λ00, φ00); - d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; - d3_geo_centroid.point = d3_geo_centroidPoint; - }; - - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), - x = cosφ * Math.cos(λ), - y = cosφ * Math.sin(λ), - z = Math.sin(φ), - cx = y0 * z - z0 * y, - cy = z0 * x - x0 * z, - cz = x0 * y - y0 * x, - m = Math.sqrt(cx * cx + cy * cy + cz * cz), - u = x0 * x + y0 * y + z0 * z, - v = m && -d3_acos(u) / m, // area weight - w = Math.atan2(m, u); // line weight - d3_geo_centroidX2 += v * cx; - d3_geo_centroidY2 += v * cy; - d3_geo_centroidZ2 += v * cz; - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } -} diff --git a/src/geo/circle.js b/src/geo/circle.js deleted file mode 100644 index f14faa5e64a184..00000000000000 --- a/src/geo/circle.js +++ /dev/null @@ -1,81 +0,0 @@ -import "../math/trigonometry"; -import "cartesian"; -import "geo"; -import "rotation"; -import "spherical"; - -d3.geo.circle = function() { - var origin = [0, 0], - angle, - precision = 6, - interpolate; - - function circle() { - var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, - rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, - ring = []; - - interpolate(null, null, 1, { - point: function(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= d3_degrees, x[1] *= d3_degrees; - } - }); - - return {type: "Polygon", coordinates: [ring]}; - } - - circle.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return circle; - }; - - circle.angle = function(x) { - if (!arguments.length) return angle; - interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); - return circle; - }; - - circle.precision = function(_) { - if (!arguments.length) return precision; - interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); - return circle; - }; - - return circle.angle(90); -}; - -// Interpolates along a circle centered at [0°, 0°], with a given radius and -// precision. -function d3_geo_circleInterpolate(radius, precision) { - var cr = Math.cos(radius), - sr = Math.sin(radius); - return function(from, to, direction, listener) { - var step = direction * precision; - if (from != null) { - from = d3_geo_circleAngle(cr, from); - to = d3_geo_circleAngle(cr, to); - if (direction > 0 ? from < to: from > to) from += direction * 2 * π; - } else { - from = radius + direction * 2 * π; - to = radius - .5 * step; - } - for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { - listener.point((point = d3_geo_spherical([ - cr, - -sr * Math.cos(t), - -sr * Math.sin(t) - ]))[0], point[1]); - } - }; -} - -// Signed angle of a cartesian point relative to [cr, 0, 0]. -function d3_geo_circleAngle(cr, point) { - var a = d3_geo_cartesian(point); - a[0] -= cr; - d3_geo_cartesianNormalize(a); - var angle = d3_acos(-a[1]); - return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); -} diff --git a/src/geo/clip-antimeridian.js b/src/geo/clip-antimeridian.js deleted file mode 100644 index bfed5ec416ac5f..00000000000000 --- a/src/geo/clip-antimeridian.js +++ /dev/null @@ -1,101 +0,0 @@ -import "../core/true"; -import "../math/trigonometry"; -import "clip"; -import "point-in-polygon"; - -var d3_geo_clipAntimeridian = d3_geo_clip( - d3_true, - d3_geo_clipAntimeridianLine, - d3_geo_clipAntimeridianInterpolate, - d3_geo_clipAntimeridianPolygonContains); - -// Takes a line and cuts into visible segments. Return values: -// 0: there were intersections or the line was empty. -// 1: no intersections. -// 2: there were intersections, and the first and last segments should be -// rejoined. -function d3_geo_clipAntimeridianLine(listener) { - var λ0 = NaN, - φ0 = NaN, - sλ0 = NaN, - clean; // no intersections - - return { - lineStart: function() { - listener.lineStart(); - clean = 1; - }, - point: function(λ1, φ1) { - var sλ1 = λ1 > 0 ? π : -π, - dλ = Math.abs(λ1 - λ0); - if (Math.abs(dλ - π) < ε) { // line crosses a pole - listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - listener.point( λ1, φ0); - clean = 0; - } else if (sλ0 !== sλ1 && dλ >= π) { // line crosses antimeridian - // handle degeneracies - if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; - if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; - φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - clean = 0; - } - listener.point(λ0 = λ1, φ0 = φ1); - sλ0 = sλ1; - }, - lineEnd: function() { - listener.lineEnd(); - λ0 = φ0 = NaN; - }, - // if there are intersections, we always rejoin the first and last segments. - clean: function() { return 2 - clean; } - }; -} - -function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { - var cosφ0, - cosφ1, - sinλ0_λ1 = Math.sin(λ0 - λ1); - return Math.abs(sinλ0_λ1) > ε - ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) - / (cosφ0 * cosφ1 * sinλ0_λ1)) - : (φ0 + φ1) / 2; -} - -function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { - var φ; - if (from == null) { - φ = direction * π / 2; - listener.point(-π, φ); - listener.point( 0, φ); - listener.point( π, φ); - listener.point( π, 0); - listener.point( π, -φ); - listener.point( 0, -φ); - listener.point(-π, -φ); - listener.point(-π, 0); - listener.point(-π, φ); - } else if (Math.abs(from[0] - to[0]) > ε) { - var s = (from[0] < to[0] ? 1 : -1) * π; - φ = direction * s / 2; - listener.point(-s, φ); - listener.point( 0, φ); - listener.point( s, φ); - } else { - listener.point(to[0], to[1]); - } -} - -var d3_geo_clipAntimeridianPoint = [-π, 0]; - -function d3_geo_clipAntimeridianPolygonContains(polygon) { - return d3_geo_pointInPolygon(d3_geo_clipAntimeridianPoint, polygon); -} diff --git a/src/geo/clip-circle.js b/src/geo/clip-circle.js deleted file mode 100644 index 88f9e601d9de23..00000000000000 --- a/src/geo/clip-circle.js +++ /dev/null @@ -1,182 +0,0 @@ -import "../math/trigonometry"; -import "cartesian"; -import "clip"; -import "circle"; -import "spherical"; -import "point-in-polygon"; - -// Clip features against a small circle centered at [0°, 0°]. -function d3_geo_clipCircle(radius) { - var cr = Math.cos(radius), - smallRadius = cr > 0, - point = [radius, 0], - notHemisphere = Math.abs(cr) > ε, // TODO optimise for this common case - interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); - - return d3_geo_clip(visible, clipLine, interpolate, polygonContains); - - function visible(λ, φ) { - return Math.cos(λ) * Math.cos(φ) > cr; - } - - // Takes a line and cuts into visible segments. Return values used for - // polygon clipping: - // 0: there were intersections or the line was empty. - // 1: no intersections. - // 2: there were intersections, and the first and last segments should be - // rejoined. - function clipLine(listener) { - var point0, // previous point - c0, // code for previous point - v0, // visibility of previous point - v00, // visibility of first point - clean; // no intersections - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(λ, φ) { - var point1 = [λ, φ], - point2, - v = visible(λ, φ), - c = smallRadius - ? v ? 0 : code(λ, φ) - : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; - if (!point0 && (v00 = v0 = v)) listener.lineStart(); - // Handle degeneracies. - // TODO ignore if not clipping polygons. - if (v !== v0) { - point2 = intersect(point0, point1); - if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { - point1[0] += ε; - point1[1] += ε; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v) { - // outside going in - listener.lineStart(); - point2 = intersect(point1, point0); - listener.point(point2[0], point2[1]); - } else { - // inside going out - point2 = intersect(point0, point1); - listener.point(point2[0], point2[1]); - listener.lineEnd(); - } - point0 = point2; - } else if (notHemisphere && point0 && smallRadius ^ v) { - var t; - // If the codes for two points are different, or are both zero, - // and there this segment intersects with the small circle. - if (!(c & c0) && (t = intersect(point1, point0, true))) { - clean = 0; - if (smallRadius) { - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - } else { - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - } - } - } - if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { - listener.point(point1[0], point1[1]); - } - point0 = point1, v0 = v, c0 = c; - }, - lineEnd: function() { - if (v0) listener.lineEnd(); - point0 = null; - }, - // Rejoin first and last segments if there were intersections and the first - // and last points were visible. - clean: function() { return clean | ((v00 && v0) << 1); } - }; - } - - // Intersects the great circle between a and b with the clip circle. - function intersect(a, b, two) { - var pa = d3_geo_cartesian(a), - pb = d3_geo_cartesian(b); - - // We have two planes, n1.p = d1 and n2.p = d2. - // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2). - var n1 = [1, 0, 0], // normal - n2 = d3_geo_cartesianCross(pa, pb), - n2n2 = d3_geo_cartesianDot(n2, n2), - n1n2 = n2[0], // d3_geo_cartesianDot(n1, n2), - determinant = n2n2 - n1n2 * n1n2; - - // Two polar points. - if (!determinant) return !two && a; - - var c1 = cr * n2n2 / determinant, - c2 = -cr * n1n2 / determinant, - n1xn2 = d3_geo_cartesianCross(n1, n2), - A = d3_geo_cartesianScale(n1, c1), - B = d3_geo_cartesianScale(n2, c2); - d3_geo_cartesianAdd(A, B); - - // Solve |p(t)|^2 = 1. - var u = n1xn2, - w = d3_geo_cartesianDot(A, u), - uu = d3_geo_cartesianDot(u, u), - t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); - - if (t2 < 0) return; - - var t = Math.sqrt(t2), - q = d3_geo_cartesianScale(u, (-w - t) / uu); - d3_geo_cartesianAdd(q, A); - q = d3_geo_spherical(q); - if (!two) return q; - - // Two intersection points. - var λ0 = a[0], - λ1 = b[0], - φ0 = a[1], - φ1 = b[1], - z; - if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; - var δλ = λ1 - λ0, - polar = Math.abs(δλ - π) < ε, - meridian = polar || δλ < ε; - - if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; - - // Check that the first point is between a and b. - if (meridian - ? polar - ? φ0 + φ1 > 0 ^ q[1] < (Math.abs(q[0] - λ0) < ε ? φ0 : φ1) - : φ0 <= q[1] && q[1] <= φ1 - : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { - var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); - d3_geo_cartesianAdd(q1, A); - return [q, d3_geo_spherical(q1)]; - } - } - - // Generates a 4-bit vector representing the location of a point relative to - // the small circle's bounding box. - function code(λ, φ) { - var r = smallRadius ? radius : π - radius, - code = 0; - if (λ < -r) code |= 1; // left - else if (λ > r) code |= 2; // right - if (φ < -r) code |= 4; // below - else if (φ > r) code |= 8; // above - return code; - } - - function polygonContains(polygon) { - return d3_geo_pointInPolygon(point, polygon); - } -} diff --git a/src/geo/clip-extent.js b/src/geo/clip-extent.js deleted file mode 100644 index e11eaa9116e047..00000000000000 --- a/src/geo/clip-extent.js +++ /dev/null @@ -1,234 +0,0 @@ -import "../arrays/merge"; -import "../math/trigonometry"; -import "geo"; -import "clip"; -import "clip-polygon"; - -var d3_geo_clipExtentMAX = 1e9; - -d3.geo.clipExtent = function() { - var x0, y0, x1, y1, - stream, - clip, - clipExtent = { - stream: function(output) { - if (stream) stream.valid = false; - stream = clip(output); - stream.valid = true; // allow caching by d3.geo.path - return stream; - }, - extent: function(_) { - if (!arguments.length) return [[x0, y0], [x1, y1]]; - clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); - if (stream) stream.valid = false, stream = null; - return clipExtent; - } - }; - return clipExtent.extent([[0, 0], [960, 500]]); -}; - -function d3_geo_clipExtent(x0, y0, x1, y1) { - return function(listener) { - var listener_ = listener, - bufferListener = d3_geo_clipBufferListener(), - segments, - polygon, - ring; - - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - listener = bufferListener; - segments = []; - polygon = []; - }, - polygonEnd: function() { - listener = listener_; - if ((segments = d3.merge(segments)).length) { - listener.polygonStart(); - d3_geo_clipPolygon(segments, compare, inside, interpolate, listener); - listener.polygonEnd(); - } else if (insidePolygon([x0, y0])) { - listener.polygonStart(), listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(), listener.polygonEnd(); - } - segments = polygon = ring = null; - } - }; - - function inside(point) { - var a = corner(point, -1), - i = insidePolygon([a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0]); - return i; - } - - function insidePolygon(p) { - var wn = 0, // the winding number counter - n = polygon.length, - y = p[1]; - - for (var i = 0; i < n; ++i) { - for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { - b = v[j]; - if (a[1] <= y) { - if (b[1] > y && isLeft(a, b, p) > 0) ++wn; - } else { - if (b[1] <= y && isLeft(a, b, p) < 0) --wn; - } - a = b; - } - } - return wn !== 0; - } - - function isLeft(a, b, c) { - return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); - } - - function interpolate(from, to, direction, listener) { - var a = 0, a1 = 0; - if (from == null || - (a = corner(from, direction)) !== (a1 = corner(to, direction)) || - comparePoints(from, to) < 0 ^ direction > 0) { - do { - listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); - } while ((a = (a + direction + 4) % 4) !== a1); - } else { - listener.point(to[0], to[1]); - } - } - - function visible(x, y) { - return x0 <= x && x <= x1 && y0 <= y && y <= y1; - } - - function point(x, y) { - if (visible(x, y)) listener.point(x, y); - } - - var x__, y__, v__, // first point - x_, y_, v_, // previous point - first; - - function lineStart() { - clip.point = linePoint; - if (polygon) polygon.push(ring = []); - first = true; - v_ = false; - x_ = y_ = NaN; - } - - function lineEnd() { - // TODO rather than special-case polygons, simply handle them separately. - // Ideally, coincident intersection points should be jittered to avoid - // clipping issues. - if (segments) { - linePoint(x__, y__); - if (v__ && v_) bufferListener.rejoin(); - segments.push(bufferListener.buffer()); - } - clip.point = point; - if (v_) listener.lineEnd(); - } - - function linePoint(x, y) { - x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); - y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); - var v = visible(x, y); - if (polygon) ring.push([x, y]); - if (first) { - x__ = x, y__ = y, v__ = v; - first = false; - if (v) { - listener.lineStart(); - listener.point(x, y); - } - } else { - if (v && v_) listener.point(x, y); - else { - var a = [x_, y_], - b = [x, y]; - if (clipLine(a, b)) { - if (!v_) { - listener.lineStart(); - listener.point(a[0], a[1]); - } - listener.point(b[0], b[1]); - if (!v) listener.lineEnd(); - } else if (v) { - listener.lineStart(); - listener.point(x, y); - } - } - } - x_ = x, y_ = y, v_ = v; - } - - return clip; - }; - - function corner(p, direction) { - return Math.abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 - : Math.abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 - : Math.abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 - : direction > 0 ? 3 : 2; // Math.abs(p[1] - y1) < ε - } - - function compare(a, b) { - return comparePoints(a.point, b.point); - } - - function comparePoints(a, b) { - var ca = corner(a, 1), - cb = corner(b, 1); - return ca !== cb ? ca - cb - : ca === 0 ? b[1] - a[1] - : ca === 1 ? a[0] - b[0] - : ca === 2 ? a[1] - b[1] - : b[0] - a[0]; - } - - // Liang–Barsky line clipping. - function clipLine(a, b) { - var dx = b[0] - a[0], - dy = b[1] - a[1], - t = [0, 1]; - - if (Math.abs(dx) < ε && Math.abs(dy) < ε) return x0 <= a[0] && a[0] <= x1 && y0 <= a[1] && a[1] <= y1; - - if (d3_geo_clipExtentT(x0 - a[0], dx, t) && - d3_geo_clipExtentT(a[0] - x1, -dx, t) && - d3_geo_clipExtentT(y0 - a[1], dy, t) && - d3_geo_clipExtentT(a[1] - y1, -dy, t)) { - if (t[1] < 1) { - b[0] = a[0] + t[1] * dx; - b[1] = a[1] + t[1] * dy; - } - if (t[0] > 0) { - a[0] += t[0] * dx; - a[1] += t[0] * dy; - } - return true; - } - - return false; - } -} - -function d3_geo_clipExtentT(num, denominator, t) { - if (Math.abs(denominator) < ε) return num <= 0; - - var u = num / denominator; - - if (denominator > 0) { - if (u > t[1]) return false; - if (u > t[0]) t[0] = u; - } else { - if (u < t[0]) return false; - if (u < t[1]) t[1] = u; - } - return true; -} diff --git a/src/geo/clip-polygon.js b/src/geo/clip-polygon.js deleted file mode 100644 index db31260914ebbc..00000000000000 --- a/src/geo/clip-polygon.js +++ /dev/null @@ -1,94 +0,0 @@ -import "../math/trigonometry"; -import "spherical"; - -// General spherical polygon clipping algorithm: takes a polygon, cuts it into -// visible line segments and rejoins the segments by interpolating along the -// clip edge. -function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) { - var subject = [], - clip = []; - - segments.forEach(function(segment) { - if ((n = segment.length - 1) <= 0) return; - var n, p0 = segment[0], p1 = segment[n]; - - // If the first and last points of a segment are coincident, then treat as - // a closed ring. - // TODO if all rings are closed, then the winding order of the exterior - // ring should be checked. - if (d3_geo_sphericalEqual(p0, p1)) { - listener.lineStart(); - for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); - listener.lineEnd(); - return; - } - - var a = {point: p0, points: segment, other: null, visited: false, entry: true, subject: true}, - b = {point: p0, points: [p0], other: a, visited: false, entry: false, subject: false}; - a.other = b; - subject.push(a); - clip.push(b); - a = {point: p1, points: [p1], other: null, visited: false, entry: false, subject: true}; - b = {point: p1, points: [p1], other: a, visited: false, entry: true, subject: false}; - a.other = b; - subject.push(a); - clip.push(b); - }); - clip.sort(compare); - d3_geo_clipPolygonLinkCircular(subject); - d3_geo_clipPolygonLinkCircular(clip); - if (!subject.length) return; - - if (inside) for (var i = 1, e = !inside(clip[0].point), n = clip.length; i < n; ++i) { - clip[i].entry = (e = !e); - } - - var start = subject[0], - current, - points, - point; - while (1) { - // Find first unvisited intersection. - current = start; - while (current.visited) if ((current = current.next) === start) return; - points = current.points; - listener.lineStart(); - do { - current.visited = current.other.visited = true; - if (current.entry) { - if (current.subject) { - for (var i = 0; i < points.length; i++) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.point, current.next.point, 1, listener); - } - current = current.next; - } else { - if (current.subject) { - points = current.prev.points; - for (var i = points.length; --i >= 0;) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.point, current.prev.point, -1, listener); - } - current = current.prev; - } - current = current.other; - points = current.points; - } while (!current.visited); - listener.lineEnd(); - } -} - -function d3_geo_clipPolygonLinkCircular(array) { - if (!(n = array.length)) return; - var n, - i = 0, - a = array[0], - b; - while (++i < n) { - a.next = b = array[i]; - b.prev = a; - a = b; - } - a.next = b = array[0]; - b.prev = a; -} diff --git a/src/geo/clip.js b/src/geo/clip.js deleted file mode 100644 index 8f6e22b1875f9d..00000000000000 --- a/src/geo/clip.js +++ /dev/null @@ -1,135 +0,0 @@ -import "../arrays/merge"; -import "../core/noop"; -import "../math/trigonometry"; -import "clip-polygon"; - -function d3_geo_clip(pointVisible, clipLine, interpolate, polygonContains) { - return function(listener) { - var line = clipLine(listener); - - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - segments = []; - polygon = []; - listener.polygonStart(); - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - - segments = d3.merge(segments); - if (segments.length) { - d3_geo_clipPolygon(segments, d3_geo_clipSort, null, interpolate, listener); - } else if (polygonContains(polygon)) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - listener.polygonEnd(); - segments = polygon = null; - }, - sphere: function() { - listener.polygonStart(); - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - listener.polygonEnd(); - } - }; - - function point(λ, φ) { if (pointVisible(λ, φ)) listener.point(λ, φ); } - function pointLine(λ, φ) { line.point(λ, φ); } - function lineStart() { clip.point = pointLine; line.lineStart(); } - function lineEnd() { clip.point = point; line.lineEnd(); } - - var segments; - - var buffer = d3_geo_clipBufferListener(), - ringListener = clipLine(buffer), - polygon, - ring; - - function pointRing(λ, φ) { - ringListener.point(λ, φ); - ring.push([λ, φ]); - } - - function ringStart() { - ringListener.lineStart(); - ring = []; - } - - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringListener.lineEnd(); - - var clean = ringListener.clean(), - ringSegments = buffer.buffer(), - segment, - n = ringSegments.length; - - ring.pop(); - polygon.push(ring); - ring = null; - - if (!n) return; - - // No intersections. - if (clean & 1) { - segment = ringSegments[0]; - var n = segment.length - 1, - i = -1, - point; - listener.lineStart(); - while (++i < n) listener.point((point = segment[i])[0], point[1]); - listener.lineEnd(); - return; - } - - // Rejoin connected segments. - // TODO reuse bufferListener.rejoin()? - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - - segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); - } - - return clip; - }; -} - -function d3_geo_clipSegmentLength1(segment) { - return segment.length > 1; -} - -function d3_geo_clipBufferListener() { - var lines = [], - line; - return { - lineStart: function() { lines.push(line = []); }, - point: function(λ, φ) { line.push([λ, φ]); }, - lineEnd: d3_noop, - buffer: function() { - var buffer = lines; - lines = []; - line = null; - return buffer; - }, - rejoin: function() { - if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); - } - }; -} - -// Intersection points are sorted along the clip edge. For both antimeridian -// cutting and circle clipping, the same comparison is used. -function d3_geo_clipSort(a, b) { - return ((a = a.point)[0] < 0 ? a[1] - π / 2 - ε : π / 2 - a[1]) - - ((b = b.point)[0] < 0 ? b[1] - π / 2 - ε : π / 2 - b[1]); -} diff --git a/src/geo/compose.js b/src/geo/compose.js deleted file mode 100644 index fe374ef820eeeb..00000000000000 --- a/src/geo/compose.js +++ /dev/null @@ -1,12 +0,0 @@ -function d3_geo_compose(a, b) { - - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } - - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), x && a.invert(x[0], x[1]); - }; - - return compose; -} diff --git a/src/geo/conic-conformal.js b/src/geo/conic-conformal.js deleted file mode 100644 index 3127a4e56c0bc8..00000000000000 --- a/src/geo/conic-conformal.js +++ /dev/null @@ -1,36 +0,0 @@ -import "../math/trigonometry"; -import "conic"; -import "geo"; -import "projection"; - -function d3_geo_conicConformal(φ0, φ1) { - var cosφ0 = Math.cos(φ0), - t = function(φ) { return Math.tan(π / 4 + φ / 2); }, - n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), - F = cosφ0 * Math.pow(t(φ0), n) / n; - - if (!n) return d3_geo_mercator; - - function forward(λ, φ) { - var ρ = Math.abs(Math.abs(φ) - π / 2) < ε ? 0 : F / Math.pow(t(φ), n); - return [ - ρ * Math.sin(n * λ), - F - ρ * Math.cos(n * λ) - ]; - } - - forward.invert = function(x, y) { - var ρ0_y = F - y, - ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); - return [ - Math.atan2(x, ρ0_y) / n, - 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - π / 2 - ]; - }; - - return forward; -} - -(d3.geo.conicConformal = function() { - return d3_geo_conic(d3_geo_conicConformal); -}).raw = d3_geo_conicConformal; diff --git a/src/geo/conic-equal-area.js b/src/geo/conic-equal-area.js deleted file mode 100644 index 7ccfb32ebbe44d..00000000000000 --- a/src/geo/conic-equal-area.js +++ /dev/null @@ -1,33 +0,0 @@ -import "../math/trigonometry"; -import "geo"; -import "conic"; -import "projection"; - -function d3_geo_conicEqualArea(φ0, φ1) { - var sinφ0 = Math.sin(φ0), - n = (sinφ0 + Math.sin(φ1)) / 2, - C = 1 + sinφ0 * (2 * n - sinφ0), - ρ0 = Math.sqrt(C) / n; - - function forward(λ, φ) { - var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; - return [ - ρ * Math.sin(λ *= n), - ρ0 - ρ * Math.cos(λ) - ]; - } - - forward.invert = function(x, y) { - var ρ0_y = ρ0 - y; - return [ - Math.atan2(x, ρ0_y) / n, - d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) - ]; - }; - - return forward; -} - -(d3.geo.conicEqualArea = function() { - return d3_geo_conic(d3_geo_conicEqualArea); -}).raw = d3_geo_conicEqualArea; diff --git a/src/geo/conic-equidistant.js b/src/geo/conic-equidistant.js deleted file mode 100644 index ff689c41911703..00000000000000 --- a/src/geo/conic-equidistant.js +++ /dev/null @@ -1,35 +0,0 @@ -import "../math/trigonometry"; -import "conic"; -import "equirectangular"; -import "geo"; -import "projection"; - -function d3_geo_conicEquidistant(φ0, φ1) { - var cosφ0 = Math.cos(φ0), - n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), - G = cosφ0 / n + φ0; - - if (Math.abs(n) < ε) return d3_geo_equirectangular; - - function forward(λ, φ) { - var ρ = G - φ; - return [ - ρ * Math.sin(n * λ), - G - ρ * Math.cos(n * λ) - ]; - } - - forward.invert = function(x, y) { - var ρ0_y = G - y; - return [ - Math.atan2(x, ρ0_y) / n, - G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) - ]; - }; - - return forward; -} - -(d3.geo.conicEquidistant = function() { - return d3_geo_conic(d3_geo_conicEquidistant); -}).raw = d3_geo_conicEquidistant; diff --git a/src/geo/conic.js b/src/geo/conic.js deleted file mode 100644 index 8377ec5bbeb977..00000000000000 --- a/src/geo/conic.js +++ /dev/null @@ -1,16 +0,0 @@ -import "../math/trigonometry"; -import "projection"; - -function d3_geo_conic(projectAt) { - var φ0 = 0, - φ1 = π / 3, - m = d3_geo_projectionMutator(projectAt), - p = m(φ0, φ1); - - p.parallels = function(_) { - if (!arguments.length) return [φ0 / π * 180, φ1 / π * 180]; - return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); - }; - - return p; -} diff --git a/src/geo/distance.js b/src/geo/distance.js deleted file mode 100644 index 805dda7b0e0dea..00000000000000 --- a/src/geo/distance.js +++ /dev/null @@ -1,13 +0,0 @@ -import "../math/trigonometry"; -import "geo"; - -// Length returned in radians; multiply by radius for distance. -d3.geo.distance = function(a, b) { - var Δλ = (b[0] - a[0]) * d3_radians, - φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, - sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), - sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), - sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), - t; - return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); -}; diff --git a/src/geo/equirectangular.js b/src/geo/equirectangular.js deleted file mode 100644 index eb9cfe08ba7029..00000000000000 --- a/src/geo/equirectangular.js +++ /dev/null @@ -1,10 +0,0 @@ -import "geo"; -import "projection"; - -function d3_geo_equirectangular(λ, φ) { - return [λ, φ]; -} - -(d3.geo.equirectangular = function() { - return d3_geo_projection(d3_geo_equirectangular); -}).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; diff --git a/src/geo/geo.js b/src/geo/geo.js deleted file mode 100644 index cf220ceb04e6a7..00000000000000 --- a/src/geo/geo.js +++ /dev/null @@ -1 +0,0 @@ -d3.geo = {}; diff --git a/src/geo/gnomonic.js b/src/geo/gnomonic.js deleted file mode 100644 index 8878ad810c7b61..00000000000000 --- a/src/geo/gnomonic.js +++ /dev/null @@ -1,12 +0,0 @@ -import "azimuthal"; -import "geo"; -import "projection"; - -var d3_geo_gnomonic = d3_geo_azimuthal( - function(cosλcosφ) { return 1 / cosλcosφ; }, - Math.atan -); - -(d3.geo.gnomonic = function() { - return d3_geo_projection(d3_geo_gnomonic); -}).raw = d3_geo_gnomonic; diff --git a/src/geo/graticule.js b/src/geo/graticule.js deleted file mode 100644 index 7cc5e672cec267..00000000000000 --- a/src/geo/graticule.js +++ /dev/null @@ -1,102 +0,0 @@ -import "../arrays/range"; -import "../math/trigonometry"; -import "geo"; - -d3.geo.graticule = function() { - var x1, x0, X1, X0, - y1, y0, Y1, Y0, - dx = 10, dy = dx, DX = 90, DY = 360, - x, y, X, Y, - precision = 2.5; - - function graticule() { - return {type: "MultiLineString", coordinates: lines()}; - } - - function lines() { - return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X) - .concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)) - .concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return Math.abs(x % DX) > ε; }).map(x)) - .concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return Math.abs(y % DY) > ε; }).map(y)); - } - - graticule.lines = function() { - return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; }); - }; - - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ - X(X0).concat( - Y(Y1).slice(1), - X(X1).reverse().slice(1), - Y(Y0).reverse().slice(1)) - ] - }; - }; - - graticule.extent = function(_) { - if (!arguments.length) return graticule.minorExtent(); - return graticule.majorExtent(_).minorExtent(_); - }; - - graticule.majorExtent = function(_) { - if (!arguments.length) return [[X0, Y0], [X1, Y1]]; - X0 = +_[0][0], X1 = +_[1][0]; - Y0 = +_[0][1], Y1 = +_[1][1]; - if (X0 > X1) _ = X0, X0 = X1, X1 = _; - if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; - return graticule.precision(precision); - }; - - graticule.minorExtent = function(_) { - if (!arguments.length) return [[x0, y0], [x1, y1]]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; - - graticule.step = function(_) { - if (!arguments.length) return graticule.minorStep(); - return graticule.majorStep(_).minorStep(_); - }; - - graticule.majorStep = function(_) { - if (!arguments.length) return [DX, DY]; - DX = +_[0], DY = +_[1]; - return graticule; - }; - - graticule.minorStep = function(_) { - if (!arguments.length) return [dx, dy]; - dx = +_[0], dy = +_[1]; - return graticule; - }; - - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = d3_geo_graticuleX(y0, y1, 90); - y = d3_geo_graticuleY(x0, x1, precision); - X = d3_geo_graticuleX(Y0, Y1, 90); - Y = d3_geo_graticuleY(X0, X1, precision); - return graticule; - }; - - return graticule - .majorExtent([[-180, -90 + ε], [180, 90 - ε]]) - .minorExtent([[-180, -80 - ε], [180, 80 + ε]]); -}; - -function d3_geo_graticuleX(y0, y1, dy) { - var y = d3.range(y0, y1 - ε, dy).concat(y1); - return function(x) { return y.map(function(y) { return [x, y]; }); }; -} - -function d3_geo_graticuleY(x0, x1, dx) { - var x = d3.range(x0, x1 - ε, dx).concat(x1); - return function(y) { return x.map(function(x) { return [x, y]; }); }; -} diff --git a/src/geo/greatArc.js b/src/geo/greatArc.js deleted file mode 100644 index a60a4888896915..00000000000000 --- a/src/geo/greatArc.js +++ /dev/null @@ -1,42 +0,0 @@ -import "../core/source"; -import "../core/target"; -import "geo"; -import "distance"; - -// @deprecated use {type: "LineString"} or d3.geo.distance instead. -d3.geo.greatArc = function() { - var source = d3_source, source_, - target = d3_target, target_; - - function greatArc() { - return {type: "LineString", coordinates: [ - source_ || source.apply(this, arguments), - target_ || target.apply(this, arguments) - ]}; - } - - greatArc.distance = function() { - return d3.geo.distance( - source_ || source.apply(this, arguments), - target_ || target.apply(this, arguments) - ); - }; - - greatArc.source = function(_) { - if (!arguments.length) return source; - source = _, source_ = typeof _ === "function" ? null : _; - return greatArc; - }; - - greatArc.target = function(_) { - if (!arguments.length) return target; - target = _, target_ = typeof _ === "function" ? null : _; - return greatArc; - }; - - greatArc.precision = function() { - return arguments.length ? greatArc : 0; - }; - - return greatArc; -}; diff --git a/src/geo/index.js b/src/geo/index.js deleted file mode 100644 index c95f341623bfe0..00000000000000 --- a/src/geo/index.js +++ /dev/null @@ -1,33 +0,0 @@ -import "geo"; -import "area"; -import "bounds"; -import "centroid"; -import "circle"; -import "distance"; -import "graticule"; -import "greatArc"; -import "interpolate"; -import "length"; -import "path"; -import "path-area"; -import "path-buffer"; -import "path-centroid"; -import "path-context"; -import "projection"; -import "rotation"; -import "stream"; -import "transform"; -import "albers"; -import "albers-usa"; -import "azimuthal"; -import "azimuthal-equal-area"; -import "azimuthal-equidistant"; -import "conic-conformal"; -import "conic-equal-area"; -import "conic-equidistant"; -import "equirectangular"; -import "gnomonic"; -import "mercator"; -import "orthographic"; -import "stereographic"; -import "transverse-mercator"; diff --git a/src/geo/interpolate.js b/src/geo/interpolate.js deleted file mode 100644 index dba105baa0e9ee..00000000000000 --- a/src/geo/interpolate.js +++ /dev/null @@ -1,38 +0,0 @@ -import "../math/trigonometry"; -import "geo"; - -d3.geo.interpolate = function(source, target) { - return d3_geo_interpolate( - source[0] * d3_radians, source[1] * d3_radians, - target[0] * d3_radians, target[1] * d3_radians - ); -}; - -function d3_geo_interpolate(x0, y0, x1, y1) { - var cy0 = Math.cos(y0), - sy0 = Math.sin(y0), - cy1 = Math.cos(y1), - sy1 = Math.sin(y1), - kx0 = cy0 * Math.cos(x0), - ky0 = cy0 * Math.sin(x0), - kx1 = cy1 * Math.cos(x1), - ky1 = cy1 * Math.sin(x1), - d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), - k = 1 / Math.sin(d); - - var interpolate = d ? function(t) { - var B = Math.sin(t *= d) * k, - A = Math.sin(d - t) * k, - x = A * kx0 + B * kx1, - y = A * ky0 + B * ky1, - z = A * sy0 + B * sy1; - return [ - Math.atan2(y, x) * d3_degrees, - Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees - ]; - } : function() { return [x0 * d3_degrees, y0 * d3_degrees]; }; - - interpolate.distance = d; - - return interpolate; -}; diff --git a/src/geo/length.js b/src/geo/length.js deleted file mode 100644 index fdd51010ee1f49..00000000000000 --- a/src/geo/length.js +++ /dev/null @@ -1,43 +0,0 @@ -import "../core/noop"; -import "../math/trigonometry"; -import "geo"; -import "stream"; - -d3.geo.length = function(object) { - d3_geo_lengthSum = 0; - d3.geo.stream(object, d3_geo_length); - return d3_geo_lengthSum; -}; - -var d3_geo_lengthSum; - -var d3_geo_length = { - sphere: d3_noop, - point: d3_noop, - lineStart: d3_geo_lengthLineStart, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop -}; - -function d3_geo_lengthLineStart() { - var λ0, sinφ0, cosφ0; - - d3_geo_length.point = function(λ, φ) { - λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); - d3_geo_length.point = nextPoint; - }; - - d3_geo_length.lineEnd = function() { - d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; - }; - - function nextPoint(λ, φ) { - var sinφ = Math.sin(φ *= d3_radians), - cosφ = Math.cos(φ), - t = Math.abs((λ *= d3_radians) - λ0), - cosΔλ = Math.cos(t); - d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; - } -} diff --git a/src/geo/mercator.js b/src/geo/mercator.js deleted file mode 100644 index 7ef65078d65618..00000000000000 --- a/src/geo/mercator.js +++ /dev/null @@ -1,48 +0,0 @@ -import "../math/trigonometry"; -import "geo"; -import "projection"; - -function d3_geo_mercator(λ, φ) { - return [λ, Math.log(Math.tan(π / 4 + φ / 2))]; -} - -d3_geo_mercator.invert = function(x, y) { - return [x, 2 * Math.atan(Math.exp(y)) - π / 2]; -}; - -function d3_geo_mercatorProjection(project) { - var m = d3_geo_projection(project), - scale = m.scale, - translate = m.translate, - clipExtent = m.clipExtent, - clipAuto; - - m.scale = function() { - var v = scale.apply(m, arguments); - return v === m ? (clipAuto ? m.clipExtent(null) : m) : v; - }; - - m.translate = function() { - var v = translate.apply(m, arguments); - return v === m ? (clipAuto ? m.clipExtent(null) : m) : v; - }; - - m.clipExtent = function(_) { - var v = clipExtent.apply(m, arguments); - if (v === m) { - if (clipAuto = _ == null) { - var k = π * scale(), t = translate(); - clipExtent([[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]]); - } - } else if (clipAuto) { - v = null; - } - return v; - }; - - return m.clipExtent(null); -} - -(d3.geo.mercator = function() { - return d3_geo_mercatorProjection(d3_geo_mercator); -}).raw = d3_geo_mercator; diff --git a/src/geo/orthographic.js b/src/geo/orthographic.js deleted file mode 100644 index f51b500634fdc1..00000000000000 --- a/src/geo/orthographic.js +++ /dev/null @@ -1,12 +0,0 @@ -import "azimuthal"; -import "geo"; -import "projection"; - -var d3_geo_orthographic = d3_geo_azimuthal( - function() { return 1; }, - Math.asin -); - -(d3.geo.orthographic = function() { - return d3_geo_projection(d3_geo_orthographic); -}).raw = d3_geo_orthographic; diff --git a/src/geo/path-area.js b/src/geo/path-area.js deleted file mode 100644 index 99cb778cea716b..00000000000000 --- a/src/geo/path-area.js +++ /dev/null @@ -1,40 +0,0 @@ -import "../core/noop"; - -// TODO Unify this code with d3.geom.polygon area? - -var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - - // Only count area for polygon rings. - polygonStart: function() { - d3_geo_pathAreaPolygon = 0; - d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; - }, - polygonEnd: function() { - d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; - d3_geo_pathAreaSum += Math.abs(d3_geo_pathAreaPolygon / 2); - } -}; - -function d3_geo_pathAreaRingStart() { - var x00, y00, x0, y0; - - // For the first point, … - d3_geo_pathArea.point = function(x, y) { - d3_geo_pathArea.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - - // For subsequent points, … - function nextPoint(x, y) { - d3_geo_pathAreaPolygon += y0 * x - x0 * y; - x0 = x, y0 = y; - } - - // For the last point, return to the start. - d3_geo_pathArea.lineEnd = function() { - nextPoint(x00, y00); - }; -} diff --git a/src/geo/path-bounds.js b/src/geo/path-bounds.js deleted file mode 100644 index 53c7a06b1676eb..00000000000000 --- a/src/geo/path-bounds.js +++ /dev/null @@ -1,21 +0,0 @@ -import "../core/noop"; - -var d3_geo_pathBoundsX0, - d3_geo_pathBoundsY0, - d3_geo_pathBoundsX1, - d3_geo_pathBoundsY1; - -var d3_geo_pathBounds = { - point: d3_geo_pathBoundsPoint, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop -}; - -function d3_geo_pathBoundsPoint(x, y) { - if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; - if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; - if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; - if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; -} diff --git a/src/geo/path-buffer.js b/src/geo/path-buffer.js deleted file mode 100644 index d14a2fb2caa6b7..00000000000000 --- a/src/geo/path-buffer.js +++ /dev/null @@ -1,59 +0,0 @@ -function d3_geo_pathBuffer() { - var pointCircle = d3_geo_pathBufferCircle(4.5), - buffer = []; - - var stream = { - point: point, - - // While inside a line, override point to moveTo then lineTo. - lineStart: function() { stream.point = pointLineStart; }, - lineEnd: lineEnd, - - // While inside a polygon, override lineEnd to closePath. - polygonStart: function() { stream.lineEnd = lineEndPolygon; }, - polygonEnd: function() { stream.lineEnd = lineEnd; stream.point = point; }, - - pointRadius: function(_) { - pointCircle = d3_geo_pathBufferCircle(_); - return stream; - }, - - result: function() { - if (buffer.length) { - var result = buffer.join(""); - buffer = []; - return result; - } - } - }; - - function point(x, y) { - buffer.push("M", x, ",", y, pointCircle); - } - - function pointLineStart(x, y) { - buffer.push("M", x, ",", y); - stream.point = pointLine; - } - - function pointLine(x, y) { - buffer.push("L", x, ",", y); - } - - function lineEnd() { - stream.point = point; - } - - function lineEndPolygon() { - buffer.push("Z"); - } - - return stream; -} - -function d3_geo_pathBufferCircle(radius) { - return "m0," + radius - + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius - + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius - + "z"; -} diff --git a/src/geo/path-centroid.js b/src/geo/path-centroid.js deleted file mode 100644 index cda5897090efda..00000000000000 --- a/src/geo/path-centroid.js +++ /dev/null @@ -1,78 +0,0 @@ -import "centroid"; - -// TODO Unify this code with d3.geom.polygon centroid? -// TODO Enforce positive area for exterior, negative area for interior? - -var d3_geo_pathCentroid = { - point: d3_geo_pathCentroidPoint, - - // For lines, weight by length. - lineStart: d3_geo_pathCentroidLineStart, - lineEnd: d3_geo_pathCentroidLineEnd, - - // For polygons, weight by area. - polygonStart: function() { - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; - }, - polygonEnd: function() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; - d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; - } -}; - -function d3_geo_pathCentroidPoint(x, y) { - d3_geo_centroidX0 += x; - d3_geo_centroidY0 += y; - ++d3_geo_centroidZ0; -} - -function d3_geo_pathCentroidLineStart() { - var x0, y0; - - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - }; - - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } -} - -function d3_geo_pathCentroidLineEnd() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; -} - -function d3_geo_pathCentroidRingStart() { - var x00, y00, x0, y0; - - // For the first point, … - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); - }; - - // For subsequent points, … - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - - z = y0 * x - x0 * y; - d3_geo_centroidX2 += z * (x0 + x); - d3_geo_centroidY2 += z * (y0 + y); - d3_geo_centroidZ2 += z * 3; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - - // For the last point, return to the start. - d3_geo_pathCentroid.lineEnd = function() { - nextPoint(x00, y00); - }; -} diff --git a/src/geo/path-context.js b/src/geo/path-context.js deleted file mode 100644 index bc30df24d90c05..00000000000000 --- a/src/geo/path-context.js +++ /dev/null @@ -1,49 +0,0 @@ -import "../core/noop"; -import "../math/trigonometry"; - -function d3_geo_pathContext(context) { - var pointRadius = 4.5; - - var stream = { - point: point, - - // While inside a line, override point to moveTo then lineTo. - lineStart: function() { stream.point = pointLineStart; }, - lineEnd: lineEnd, - - // While inside a polygon, override lineEnd to closePath. - polygonStart: function() { stream.lineEnd = lineEndPolygon; }, - polygonEnd: function() { stream.lineEnd = lineEnd; stream.point = point; }, - - pointRadius: function(_) { - pointRadius = _; - return stream; - }, - - result: d3_noop - }; - - function point(x, y) { - context.moveTo(x, y); - context.arc(x, y, pointRadius, 0, 2 * π); - } - - function pointLineStart(x, y) { - context.moveTo(x, y); - stream.point = pointLine; - } - - function pointLine(x, y) { - context.lineTo(x, y); - } - - function lineEnd() { - stream.point = point; - } - - function lineEndPolygon() { - context.closePath(); - } - - return stream; -} diff --git a/src/geo/path.js b/src/geo/path.js deleted file mode 100644 index 05c33e721437d8..00000000000000 --- a/src/geo/path.js +++ /dev/null @@ -1,92 +0,0 @@ -import "../core/identity"; -import "../math/trigonometry"; -import "albers-usa"; -import "area"; -import "bounds"; -import "centroid"; -import "geo"; -import "path-area"; -import "path-bounds"; -import "path-buffer"; -import "path-centroid"; -import "path-context"; -import "projection"; -import "resample"; -import "stream"; -import "transform"; - -d3.geo.path = function() { - var pointRadius = 4.5, - projection, - context, - projectStream, - contextStream, - cacheStream; - - function path(object) { - if (object) { - if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); - if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); - d3.geo.stream(object, cacheStream); - } - return contextStream.result(); - } - - path.area = function(object) { - d3_geo_pathAreaSum = 0; - d3.geo.stream(object, projectStream(d3_geo_pathArea)); - return d3_geo_pathAreaSum; - }; - - path.centroid = function(object) { - d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = - d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = - d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); - return d3_geo_centroidZ2 ? [d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2] - : d3_geo_centroidZ1 ? [d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1] - : d3_geo_centroidZ0 ? [d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0] - : [NaN, NaN]; - }; - - path.bounds = function(object) { - d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); - d3.geo.stream(object, projectStream(d3_geo_pathBounds)); - return [[d3_geo_pathBoundsX0, d3_geo_pathBoundsY0], [d3_geo_pathBoundsX1, d3_geo_pathBoundsY1]]; - }; - - path.projection = function(_) { - if (!arguments.length) return projection; - projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; - return reset(); - }; - - path.context = function(_) { - if (!arguments.length) return context; - contextStream = (context = _) == null ? new d3_geo_pathBuffer : new d3_geo_pathContext(_); - if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); - return reset(); - }; - - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); - return path; - }; - - function reset() { - cacheStream = null; - return path; - } - - return path.projection(d3.geo.albersUsa()).context(null); -}; - -function d3_geo_pathProjectStream(project) { - var resample = d3_geo_resample(function(x, y) { return project([x * d3_degrees, y * d3_degrees]); }); - return function(stream) { - var transform = new d3_geo_transform(stream = resample(stream)); - transform.point = function(x, y) { stream.point(x * d3_radians, y * d3_radians); }; - return transform; - }; -} diff --git a/src/geo/point-in-polygon.js b/src/geo/point-in-polygon.js deleted file mode 100644 index eefac0fdc51fe8..00000000000000 --- a/src/geo/point-in-polygon.js +++ /dev/null @@ -1,68 +0,0 @@ -import "geo"; -import "area"; -import "cartesian"; -import "../math/trigonometry"; - -function d3_geo_pointInPolygon(point, polygon) { - var meridian = point[0], - parallel = point[1], - meridianNormal = [Math.sin(meridian), -Math.cos(meridian), 0], - polarAngle = 0, - winding = 0; - d3_geo_areaRingSum.reset(); - - for (var i = 0, n = polygon.length; i < n; ++i) { - var ring = polygon[i], - m = ring.length; - if (!m) continue; - var point0 = ring[0], - λ0 = point0[0], - φ0 = point0[1] / 2 + π / 4, - sinφ0 = Math.sin(φ0), - cosφ0 = Math.cos(φ0), - j = 1; - - while (true) { - if (j === m) j = 0; - point = ring[j]; - var λ = point[0], - φ = point[1] / 2 + π / 4, - sinφ = Math.sin(φ), - cosφ = Math.cos(φ), - dλ = λ - λ0, - antimeridian = Math.abs(dλ) > π, - k = sinφ0 * sinφ; - d3_geo_areaRingSum.add(Math.atan2(k * Math.sin(dλ), cosφ0 * cosφ + k * Math.cos(dλ))); - - polarAngle += antimeridian ? dλ + (dλ >= 0 ? 2 : -2) * π : dλ; - - // Are the longitudes either side of the point's meridian, and are the - // latitudes smaller than the parallel? - if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { - var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); - d3_geo_cartesianNormalize(arc); - var intersection = d3_geo_cartesianCross(meridianNormal, arc); - d3_geo_cartesianNormalize(intersection); - var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); - if (parallel > φarc) { - winding += antimeridian ^ dλ >= 0 ? 1 : -1; - } - } - if (!j++) break; - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; - } - } - - // First, determine whether the South pole is inside or outside: - // - // It is inside if: - // * the polygon winds around it in a clockwise direction. - // * the polygon does not (cumulatively) wind around it, but has a negative - // (counter-clockwise) area. - // - // Second, count the (signed) number of times a segment crosses a meridian - // from the point to the South pole. If it is zero, then the point is the - // same side as the South pole. - - return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ (winding & 1); -} diff --git a/src/geo/projection.js b/src/geo/projection.js deleted file mode 100644 index 25406374755438..00000000000000 --- a/src/geo/projection.js +++ /dev/null @@ -1,125 +0,0 @@ -import "../core/identity"; -import "../core/rebind"; -import "../math/trigonometry"; -import "clip-antimeridian"; -import "clip-circle"; -import "clip-extent"; -import "compose"; -import "geo"; -import "path"; -import "resample"; -import "rotation"; -import "stream"; -import "transform"; - -d3.geo.projection = d3_geo_projection; -d3.geo.projectionMutator = d3_geo_projectionMutator; - -function d3_geo_projection(project) { - return d3_geo_projectionMutator(function() { return project; })(); -} - -function d3_geo_projectionMutator(projectAt) { - var project, - rotate, - projectRotate, - projectResample = d3_geo_resample(function(x, y) { x = project(x, y); return [x[0] * k + δx, δy - x[1] * k]; }), - k = 150, // scale - x = 480, y = 250, // translate - λ = 0, φ = 0, // center - δλ = 0, δφ = 0, δγ = 0, // rotate - δx, δy, // center - preclip = d3_geo_clipAntimeridian, - postclip = d3_identity, - clipAngle = null, - clipExtent = null, - stream; - - function projection(point) { - point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); - return [point[0] * k + δx, δy - point[1] * k]; - } - - function invert(point) { - point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); - return point && [point[0] * d3_degrees, point[1] * d3_degrees]; - } - - projection.stream = function(output) { - if (stream) stream.valid = false; - stream = d3_geo_projectionRadiansRotate(rotate, preclip(projectResample(postclip(output)))); - stream.valid = true; // allow caching by d3.geo.path - return stream; - }; - - projection.clipAngle = function(_) { - if (!arguments.length) return clipAngle; - preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); - return invalidate(); - }; - - projection.clipExtent = function(_) { - if (!arguments.length) return clipExtent; - clipExtent = _; - postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; - return invalidate(); - }; - - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return reset(); - }; - - projection.translate = function(_) { - if (!arguments.length) return [x, y]; - x = +_[0]; - y = +_[1]; - return reset(); - }; - - projection.center = function(_) { - if (!arguments.length) return [λ * d3_degrees, φ * d3_degrees]; - λ = _[0] % 360 * d3_radians; - φ = _[1] % 360 * d3_radians; - return reset(); - }; - - projection.rotate = function(_) { - if (!arguments.length) return [δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees]; - δλ = _[0] % 360 * d3_radians; - δφ = _[1] % 360 * d3_radians; - δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; - return reset(); - }; - - d3.rebind(projection, projectResample, "precision"); - - function reset() { - projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); - var center = project(λ, φ); - δx = x - center[0] * k; - δy = y + center[1] * k; - return invalidate(); - } - - function invalidate() { - if (stream) stream.valid = false, stream = null; - return projection; - } - - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return reset(); - }; -} - -function d3_geo_projectionRadiansRotate(rotate, stream) { - var transform = new d3_geo_transform(stream); - transform.point = function(x, y) { - y = rotate(x * d3_radians, y * d3_radians), x = y[0]; - stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]); - }; - return transform; -} diff --git a/src/geo/resample.js b/src/geo/resample.js deleted file mode 100644 index 8c88b6d302a1b9..00000000000000 --- a/src/geo/resample.js +++ /dev/null @@ -1,98 +0,0 @@ -import "../math/trigonometry"; -import "cartesian"; -import "stream"; - -function d3_geo_resample(project) { - var δ2 = .5, // precision, px² - cosMinDistance = Math.cos(30 * d3_radians), // cos(minimum angular distance) - maxDepth = 16; - - function resample(stream) { - var λ00, φ00, x00, y00, a00, b00, c00, // first point - λ0, x0, y0, a0, b0, c0; // previous point - - var resample = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { stream.polygonStart(); resample.lineStart = ringStart; }, - polygonEnd: function() { stream.polygonEnd(); resample.lineStart = lineStart; } - }; - - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } - - function lineStart() { - x0 = NaN; - resample.point = linePoint; - stream.lineStart(); - } - - function linePoint(λ, φ) { - var c = d3_geo_cartesian([λ, φ]), p = project(λ, φ); - resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } - - function lineEnd() { - resample.point = point; - stream.lineEnd(); - } - - function ringStart() { - lineStart(); - resample.point = ringPoint; - resample.lineEnd = ringEnd; - } - - function ringPoint(λ, φ) { - linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resample.point = linePoint; - } - - function ringEnd() { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); - resample.lineEnd = lineEnd; - lineEnd(); - } - - return resample; - } - - function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, - dy = y1 - y0, - d2 = dx * dx + dy * dy; - if (d2 > 4 * δ2 && depth--) { - var a = a0 + a1, - b = b0 + b1, - c = c0 + c1, - m = Math.sqrt(a * a + b * b + c * c), - φ2 = Math.asin(c /= m), - λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), - p = project(λ2, φ2), - x2 = p[0], - y2 = p[1], - dx2 = x2 - x0, - dy2 = y2 - y0, - dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > δ2 // perpendicular projected distance - || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 // midpoint close to an end - || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance - resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); - } - } - } - - resample.precision = function(_) { - if (!arguments.length) return Math.sqrt(δ2); - maxDepth = (δ2 = _ * _) > 0 && 16; - return resample; - }; - - return resample; -} diff --git a/src/geo/rotation.js b/src/geo/rotation.js deleted file mode 100644 index 8c399486198cb7..00000000000000 --- a/src/geo/rotation.js +++ /dev/null @@ -1,72 +0,0 @@ -import "../math/trigonometry"; -import "equirectangular"; -import "geo"; - -d3.geo.rotation = function(rotate) { - rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); - - function forward(coordinates) { - coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - } - - forward.invert = function(coordinates) { - coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - }; - - return forward; -}; - -// Note: |δλ| must be < 2π -function d3_geo_rotation(δλ, δφ, δγ) { - return δλ ? (δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) - : d3_geo_rotationλ(δλ)) - : (δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) - : d3_geo_equirectangular); -} - -function d3_geo_forwardRotationλ(δλ) { - return function(λ, φ) { - return λ += δλ, [λ > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ]; - }; -} - -function d3_geo_rotationλ(δλ) { - var rotation = d3_geo_forwardRotationλ(δλ); - rotation.invert = d3_geo_forwardRotationλ(-δλ); - return rotation; -} - -function d3_geo_rotationφγ(δφ, δγ) { - var cosδφ = Math.cos(δφ), - sinδφ = Math.sin(δφ), - cosδγ = Math.cos(δγ), - sinδγ = Math.sin(δγ); - - function rotation(λ, φ) { - var cosφ = Math.cos(φ), - x = Math.cos(λ) * cosφ, - y = Math.sin(λ) * cosφ, - z = Math.sin(φ), - k = z * cosδφ + x * sinδφ; - return [ - Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), - d3_asin(k * cosδγ + y * sinδγ) - ]; - } - - rotation.invert = function(λ, φ) { - var cosφ = Math.cos(φ), - x = Math.cos(λ) * cosφ, - y = Math.sin(λ) * cosφ, - z = Math.sin(φ), - k = z * cosδγ - y * sinδγ; - return [ - Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), - d3_asin(k * cosδφ - x * sinδφ) - ]; - }; - - return rotation; -} diff --git a/src/geo/spherical.js b/src/geo/spherical.js deleted file mode 100644 index 50e4838cd5483c..00000000000000 --- a/src/geo/spherical.js +++ /dev/null @@ -1,12 +0,0 @@ -import "../math/trigonometry"; - -function d3_geo_spherical(cartesian) { - return [ - Math.atan2(cartesian[1], cartesian[0]), - d3_asin(cartesian[2]) - ]; -} - -function d3_geo_sphericalEqual(a, b) { - return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε; -} diff --git a/src/geo/stereographic.js b/src/geo/stereographic.js deleted file mode 100644 index 052945f8672e35..00000000000000 --- a/src/geo/stereographic.js +++ /dev/null @@ -1,12 +0,0 @@ -import "azimuthal"; -import "geo"; -import "projection"; - -var d3_geo_stereographic = d3_geo_azimuthal( - function(cosλcosφ) { return 1 / (1 + cosλcosφ); }, - function(ρ) { return 2 * Math.atan(ρ); } -); - -(d3.geo.stereographic = function() { - return d3_geo_projection(d3_geo_stereographic); -}).raw = d3_geo_stereographic; diff --git a/src/geo/stream.js b/src/geo/stream.js deleted file mode 100644 index 2119c5dd592d25..00000000000000 --- a/src/geo/stream.js +++ /dev/null @@ -1,71 +0,0 @@ -import "geo"; - -d3.geo.stream = function(object, listener) { - if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { - d3_geo_streamObjectType[object.type](object, listener); - } else { - d3_geo_streamGeometry(object, listener); - } -}; - -function d3_geo_streamGeometry(geometry, listener) { - if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { - d3_geo_streamGeometryType[geometry.type](geometry, listener); - } -} - -var d3_geo_streamObjectType = { - Feature: function(feature, listener) { - d3_geo_streamGeometry(feature.geometry, listener); - }, - FeatureCollection: function(object, listener) { - var features = object.features, i = -1, n = features.length; - while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); - } -}; - -var d3_geo_streamGeometryType = { - Sphere: function(object, listener) { - listener.sphere(); - }, - Point: function(object, listener) { - object = object.coordinates; - listener.point(object[0], object[1], object[2]); - }, - MultiPoint: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); - }, - LineString: function(object, listener) { - d3_geo_streamLine(object.coordinates, listener, 0); - }, - MultiLineString: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); - }, - Polygon: function(object, listener) { - d3_geo_streamPolygon(object.coordinates, listener); - }, - MultiPolygon: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); - }, - GeometryCollection: function(object, listener) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) d3_geo_streamGeometry(geometries[i], listener); - } -}; - -function d3_geo_streamLine(coordinates, listener, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - listener.lineStart(); - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); - listener.lineEnd(); -} - -function d3_geo_streamPolygon(coordinates, listener) { - var i = -1, n = coordinates.length; - listener.polygonStart(); - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); - listener.polygonEnd(); -} diff --git a/src/geo/transform.js b/src/geo/transform.js deleted file mode 100644 index 4bc8ff5bdd37dd..00000000000000 --- a/src/geo/transform.js +++ /dev/null @@ -1,25 +0,0 @@ -import "geo"; -import "../core/array"; - -d3.geo.transform = function(methods) { - return { - stream: function(stream) { - var transform = new d3_geo_transform(stream); - for (var k in methods) transform[k] = methods[k]; - return transform; - } - }; -}; - -function d3_geo_transform(stream) { - this.stream = stream; -} - -d3_geo_transform.prototype = { - point: function(x, y) { this.stream.point(x, y); }, - sphere: function() { this.stream.sphere(); }, - lineStart: function() { this.stream.lineStart(); }, - lineEnd: function() { this.stream.lineEnd(); }, - polygonStart: function() { this.stream.polygonStart(); }, - polygonEnd: function() { this.stream.polygonEnd(); } -}; diff --git a/src/geo/transverse-mercator.js b/src/geo/transverse-mercator.js deleted file mode 100644 index b9a7b4d56a47ca..00000000000000 --- a/src/geo/transverse-mercator.js +++ /dev/null @@ -1,23 +0,0 @@ -import "../math/trigonometry"; -import "geo"; -import "mercator"; -import "projection"; - -function d3_geo_transverseMercator(λ, φ) { - var B = Math.cos(φ) * Math.sin(λ); - return [ - Math.log((1 + B) / (1 - B)) / 2, - Math.atan2(Math.tan(φ), Math.cos(λ)) - ]; -} - -d3_geo_transverseMercator.invert = function(x, y) { - return [ - Math.atan2(d3_sinh(x), Math.cos(y)), - d3_asin(Math.sin(y) / d3_cosh(x)) - ]; -}; - -(d3.geo.transverseMercator = function() { - return d3_geo_mercatorProjection(d3_geo_transverseMercator); -}).raw = d3_geo_transverseMercator; diff --git a/src/geom/delaunay.js b/src/geom/delaunay.js deleted file mode 100644 index 47c4486459418e..00000000000000 --- a/src/geom/delaunay.js +++ /dev/null @@ -1,31 +0,0 @@ -import "geom"; -import "voronoi"; - -// @deprecated; use d3.geom.voronoi links instead. -d3.geom.delaunay = function(vertices) { - var edges = vertices.map(function() { return []; }), - triangles = []; - - // Use the Voronoi tessellation to determine Delaunay edges. - d3_geom_voronoiTessellate(vertices, function(e) { - edges[e.region.l.index].push(vertices[e.region.r.index]); - }); - - // Reconnect the edges into counterclockwise triangles. - edges.forEach(function(edge, i) { - var v = vertices[i], - cx = v[0], - cy = v[1]; - edge.forEach(function(v) { - v.angle = Math.atan2(v[0] - cx, v[1] - cy); - }); - edge.sort(function(a, b) { - return a.angle - b.angle; - }); - for (var j = 0, m = edge.length - 1; j < m; j++) { - triangles.push([v, edge[j], edge[j + 1]]); - } - }); - - return triangles; -}; diff --git a/src/geom/geom.js b/src/geom/geom.js deleted file mode 100644 index b17c4fc30609d3..00000000000000 --- a/src/geom/geom.js +++ /dev/null @@ -1 +0,0 @@ -d3.geom = {}; diff --git a/src/geom/hull.js b/src/geom/hull.js deleted file mode 100644 index 280f6af4a6008a..00000000000000 --- a/src/geom/hull.js +++ /dev/null @@ -1,120 +0,0 @@ -import "../svg/line"; -import "geom"; - -/** - * Computes the 2D convex hull of a set of points using Graham's scanning - * algorithm. The algorithm has been implemented as described in Cormen, - * Leiserson, and Rivest's Introduction to Algorithms. The running time of - * this algorithm is O(n log n), where n is the number of input points. - * - * @param vertices [[x1, y1], [x2, y2], …] - * @returns polygon [[x1, y1], [x2, y2], …] - */ -d3.geom.hull = function(vertices) { - var x = d3_svg_lineX, - y = d3_svg_lineY; - - if (arguments.length) return hull(vertices); - - function hull(data) { - if (data.length < 3) return []; - - var fx = d3_functor(x), - fy = d3_functor(y), - n = data.length, - vertices, // TODO use parallel arrays - plen = n - 1, - points = [], - stack = [], - d, - i, j, h = 0, x1, y1, x2, y2, u, v, a, sp; - - if (fx === d3_svg_lineX && y === d3_svg_lineY) vertices = data; - else for (i = 0, vertices = []; i < n; ++i) { - vertices.push([+fx.call(this, d = data[i], i), +fy.call(this, d, i)]); - } - - // find the starting ref point: leftmost point with the minimum y coord - for (i = 1; i < n; ++i) { - if (vertices[i][1] < vertices[h][1] - || vertices[i][1] == vertices[h][1] - && vertices[i][0] < vertices[h][0]) h = i; - } - - // calculate polar angles from ref point and sort - for (i = 0; i < n; ++i) { - if (i === h) continue; - y1 = vertices[i][1] - vertices[h][1]; - x1 = vertices[i][0] - vertices[h][0]; - points.push({angle: Math.atan2(y1, x1), index: i}); - } - points.sort(function(a, b) { return a.angle - b.angle; }); - - // toss out duplicate angles - a = points[0].angle; - v = points[0].index; - u = 0; - for (i = 1; i < plen; ++i) { - j = points[i].index; - if (a == points[i].angle) { - // keep angle for point most distant from the reference - x1 = vertices[v][0] - vertices[h][0]; - y1 = vertices[v][1] - vertices[h][1]; - x2 = vertices[j][0] - vertices[h][0]; - y2 = vertices[j][1] - vertices[h][1]; - if (x1 * x1 + y1 * y1 >= x2 * x2 + y2 * y2) { - points[i].index = -1; - continue; - } else { - points[u].index = -1; - } - } - a = points[i].angle; - u = i; - v = j; - } - - // initialize the stack - stack.push(h); - for (i = 0, j = 0; i < 2; ++j) { - if (points[j].index > -1) { - stack.push(points[j].index); - i++; - } - } - sp = stack.length; - - // do graham's scan - for (; j < plen; ++j) { - if (points[j].index < 0) continue; // skip tossed out points - while (!d3_geom_hullCCW(stack[sp - 2], stack[sp - 1], points[j].index, vertices)) { - --sp; - } - stack[sp++] = points[j].index; - } - - // construct the hull - var poly = []; - for (i = sp - 1; i >= 0; --i) poly.push(data[stack[i]]); - return poly; - } - - hull.x = function(_) { - return arguments.length ? (x = _, hull) : x; - }; - - hull.y = function(_) { - return arguments.length ? (y = _, hull) : y; - }; - - return hull; -}; - -// are three points in counter-clockwise order? -function d3_geom_hullCCW(i1, i2, i3, v) { - var t, a, b, c, d, e, f; - t = v[i1]; a = t[0]; b = t[1]; - t = v[i2]; c = t[0]; d = t[1]; - t = v[i3]; e = t[0]; f = t[1]; - return (f - b) * (c - a) - (d - b) * (e - a) > 0; -} diff --git a/src/geom/index.js b/src/geom/index.js deleted file mode 100644 index 9e2fb282d4c274..00000000000000 --- a/src/geom/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import "geom"; -import "hull"; -import "polygon"; -import "voronoi"; -import "delaunay"; -import "quadtree"; diff --git a/src/geom/polygon.js b/src/geom/polygon.js deleted file mode 100644 index 02383dd7bac66c..00000000000000 --- a/src/geom/polygon.js +++ /dev/null @@ -1,105 +0,0 @@ -import "../core/subclass"; -import "geom"; - -d3.geom.polygon = function(coordinates) { - d3_subclass(coordinates, d3_geom_polygonPrototype); - return coordinates; -}; - -var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; - -d3_geom_polygonPrototype.area = function() { - var i = -1, - n = this.length, - a, - b = this[n - 1], - area = 0; - - while (++i < n) { - a = b; - b = this[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - - return area * .5; -}; - -d3_geom_polygonPrototype.centroid = function(k) { - var i = -1, - n = this.length, - x = 0, - y = 0, - a, - b = this[n - 1], - c; - - if (!arguments.length) k = -1 / (6 * this.area()); - - while (++i < n) { - a = b; - b = this[i]; - c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } - - return [x * k, y * k]; -}; - -// The Sutherland-Hodgman clipping algorithm. -// Note: requires the clip polygon to be counterclockwise and convex. -d3_geom_polygonPrototype.clip = function(subject) { - var input, - closed = d3_geom_polygonClosed(subject), - i = -1, - n = this.length - d3_geom_polygonClosed(this), - j, - m, - a = this[n - 1], - b, - c, - d; - - while (++i < n) { - input = subject.slice(); - subject.length = 0; - b = this[i]; - c = input[(m = input.length - closed) - 1]; - j = -1; - while (++j < m) { - d = input[j]; - if (d3_geom_polygonInside(d, a, b)) { - if (!d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - subject.push(d); - } else if (d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - c = d; - } - if (closed) subject.push(subject[0]); - a = b; - } - - return subject; -}; - -function d3_geom_polygonInside(p, a, b) { - return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); -} - -// Intersect two infinite lines cd and ab. -function d3_geom_polygonIntersect(c, d, a, b) { - var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, - y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, - ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); - return [x1 + ua * x21, y1 + ua * y21]; -} - -// Returns true if the polygon is closed. -function d3_geom_polygonClosed(coordinates) { - var a = coordinates[0], - b = coordinates[coordinates.length - 1]; - return !(a[0] - b[0] || a[1] - b[1]); -} diff --git a/src/geom/quadtree.js b/src/geom/quadtree.js deleted file mode 100644 index c7a4e8ce07b802..00000000000000 --- a/src/geom/quadtree.js +++ /dev/null @@ -1,190 +0,0 @@ -import "../core/functor"; -import "../svg/line"; -import "geom"; - -d3.geom.quadtree = function(points, x1, y1, x2, y2) { - var x = d3_svg_lineX, - y = d3_svg_lineY, - compat; - - // For backwards-compatibility. - if (compat = arguments.length) { - x = d3_geom_quadtreeCompatX; - y = d3_geom_quadtreeCompatY; - if (compat === 3) { - y2 = y1; - x2 = x1; - y1 = x1 = 0; - } - return quadtree(points); - } - - function quadtree(data) { - var d, - fx = d3_functor(x), - fy = d3_functor(y), - xs, - ys, - i, - n, - x1_, - y1_, - x2_, - y2_; - - if (x1 != null) { - x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; - } else { - // Compute bounds, and cache points temporarily. - x2_ = y2_ = -(x1_ = y1_ = Infinity); - xs = [], ys = []; - n = data.length; - if (compat) for (i = 0; i < n; ++i) { - d = data[i]; - if (d.x < x1_) x1_ = d.x; - if (d.y < y1_) y1_ = d.y; - if (d.x > x2_) x2_ = d.x; - if (d.y > y2_) y2_ = d.y; - xs.push(d.x); - ys.push(d.y); - } else for (i = 0; i < n; ++i) { - var x_ = +fx(d = data[i], i), - y_ = +fy(d, i); - if (x_ < x1_) x1_ = x_; - if (y_ < y1_) y1_ = y_; - if (x_ > x2_) x2_ = x_; - if (y_ > y2_) y2_ = y_; - xs.push(x_); - ys.push(y_); - } - } - - // Squarify the bounds. - var dx = x2_ - x1_, - dy = y2_ - y1_; - if (dx > dy) y2_ = y1_ + dx; - else x2_ = x1_ + dy; - - // Recursively inserts the specified point p at the node n or one of its - // descendants. The bounds are defined by [x1, x2] and [y1, y2]. - function insert(n, d, x, y, x1, y1, x2, y2) { - if (isNaN(x) || isNaN(y)) return; // ignore invalid points - if (n.leaf) { - var nx = n.x, - ny = n.y; - if (nx != null) { - // If the point at this leaf node is at the same position as the new - // point we are adding, we leave the point associated with the - // internal node while adding the new point to a child node. This - // avoids infinite recursion. - if ((Math.abs(nx - x) + Math.abs(ny - y)) < .01) { - insertChild(n, d, x, y, x1, y1, x2, y2); - } else { - var nPoint = n.point; - n.x = n.y = n.point = null; - insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } else { - n.x = x, n.y = y, n.point = d; - } - } else { - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } - - // Recursively inserts the specified point [x, y] into a descendant of node - // n. The bounds are defined by [x1, x2] and [y1, y2]. - function insertChild(n, d, x, y, x1, y1, x2, y2) { - // Compute the split point, and the quadrant in which to insert p. - var sx = (x1 + x2) * .5, - sy = (y1 + y2) * .5, - right = x >= sx, - bottom = y >= sy, - i = (bottom << 1) + right; - - // Recursively insert into the child node. - n.leaf = false; - n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); - - // Update the bounds as we recurse. - if (right) x1 = sx; else x2 = sx; - if (bottom) y1 = sy; else y2 = sy; - insert(n, d, x, y, x1, y1, x2, y2); - } - - // Create the root node. - var root = d3_geom_quadtreeNode(); - - root.add = function(d) { - insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); - }; - - root.visit = function(f) { - d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); - }; - - // Insert all points. - i = -1; - if (x1 == null) { - while (++i < n) { - insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); - } - --i; // index of last insertion - } else data.forEach(root.add); - - // Discard captured fields. - xs = ys = data = d = null; - - return root; - } - - quadtree.x = function(_) { - return arguments.length ? (x = _, quadtree) : x; - }; - - quadtree.y = function(_) { - return arguments.length ? (y = _, quadtree) : y; - }; - - quadtree.extent = function(_) { - if (!arguments.length) return x1 == null ? null : [[x1, y1], [x2, y2]]; - if (_ == null) x1 = y1 = x2 = y2 = null; - else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], y2 = +_[1][1]; - return quadtree; - }; - - quadtree.size = function(_) { - if (!arguments.length) return x1 == null ? null : [x2 - x1, y2 - y1]; - if (_ == null) x1 = y1 = x2 = y2 = null; - else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; - return quadtree; - }; - - return quadtree; -}; - -function d3_geom_quadtreeCompatX(d) { return d.x; } -function d3_geom_quadtreeCompatY(d) { return d.y; } - -function d3_geom_quadtreeNode() { - return { - leaf: true, - nodes: [], - point: null, - x: null, - y: null - }; -} - -function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { - if (!f(node, x1, y1, x2, y2)) { - var sx = (x1 + x2) * .5, - sy = (y1 + y2) * .5, - children = node.nodes; - if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); - if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); - if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); - if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); - } -} diff --git a/src/geom/voronoi.js b/src/geom/voronoi.js deleted file mode 100644 index 2f66ee4425a9a2..00000000000000 --- a/src/geom/voronoi.js +++ /dev/null @@ -1,545 +0,0 @@ -import "../arrays/range"; -import "../core/functor"; -import "../math/trigonometry"; -import "../svg/line"; -import "delaunay"; -import "geom"; -import "polygon"; - -// Adapted from Nicolas Garcia Belmonte's JIT implementation: -// http://blog.thejit.org/2010/02/12/voronoi-tessellation/ -// http://blog.thejit.org/assets/voronoijs/voronoi.js -// See lib/jit/LICENSE for details. - -// Notes: -// -// This implementation does not clip the returned polygons, so if you want to -// clip them to a particular shape you will need to do that either in SVG or by -// post-processing with d3.geom.polygon's clip method. -// -// If any points are coincident or have NaN positions, the behavior of this -// method is undefined. Most likely invalid polygons will be returned. You -// should filter invalid points, and consolidate coincident points, before -// computing the tessellation. - -/** - * @param points [[x1, y1], [x2, y2], …] - * @returns polygons [[[x1, y1], [x2, y2], …], …] - */ -d3.geom.voronoi = function(points) { - var x = d3_svg_lineX, - y = d3_svg_lineY, - clipPolygon = null; - - // For backwards-compatibility. - if (arguments.length) return voronoi(points); - - function voronoi(data) { - var points, - polygons = data.map(function() { return []; }), - fx = d3_functor(x), - fy = d3_functor(y), - d, - i, - n = data.length, - Z = 1e6; - - if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; - else for (points = new Array(n), i = 0; i < n; ++i) { - points[i] = [+fx.call(this, d = data[i], i), +fy.call(this, d, i)]; - } - - d3_geom_voronoiTessellate(points, function(e) { - var s1, - s2, - x1, - x2, - y1, - y2; - if (e.a === 1 && e.b >= 0) { - s1 = e.ep.r; - s2 = e.ep.l; - } else { - s1 = e.ep.l; - s2 = e.ep.r; - } - if (e.a === 1) { - y1 = s1 ? s1.y : -Z; - x1 = e.c - e.b * y1; - y2 = s2 ? s2.y : Z; - x2 = e.c - e.b * y2; - } else { - x1 = s1 ? s1.x : -Z; - y1 = e.c - e.a * x1; - x2 = s2 ? s2.x : Z; - y2 = e.c - e.a * x2; - } - var v1 = [x1, y1], - v2 = [x2, y2]; - polygons[e.region.l.index].push(v1, v2); - polygons[e.region.r.index].push(v1, v2); - }); - - // Connect edges into counterclockwise polygons without coincident points. - polygons = polygons.map(function(polygon, i) { - var cx = points[i][0], - cy = points[i][1], - angle = polygon.map(function(v) { return Math.atan2(v[0] - cx, v[1] - cy); }), - order = d3.range(polygon.length).sort(function(a, b) { return angle[a] - angle[b]; }); - return order - .filter(function(d, i) { return !i || (angle[d] - angle[order[i - 1]] > ε); }) - .map(function(d) { return polygon[d]; }); - }); - - // Fix degenerate polygons. - polygons.forEach(function(polygon, i) { - var n = polygon.length; - if (!n) return polygon.push([-Z, -Z], [-Z, Z], [Z, Z], [Z, -Z]); - if (n > 2) return; - - var p0 = points[i], - p1 = polygon[0], - p2 = polygon[1], - x0 = p0[0], y0 = p0[1], - x1 = p1[0], y1 = p1[1], - x2 = p2[0], y2 = p2[1], - dx = Math.abs(x2 - x1), dy = y2 - y1; - - if (Math.abs(dy) < ε) { // 0° - var y = y0 < y1 ? -Z : Z; - polygon.push([-Z, y], [Z, y]); - } else if (dx < ε) { // ±90° - var x = x0 < x1 ? -Z : Z; - polygon.push([x, -Z], [x, Z]); - } else { - var y = (x2 - x1) * (y1 - y0) < (x1 - x0) * (y2 - y1) ? Z : -Z, - z = Math.abs(dy) - dx; - if (Math.abs(z) < ε) { // ±45° - polygon.push([dy < 0 ? y : -y, y]); - } else { - if (z > 0) y *= -1; - polygon.push([-Z, y], [Z, y]); - } - } - }); - - if (clipPolygon) for (i = 0; i < n; ++i) clipPolygon.clip(polygons[i]); - for (i = 0; i < n; ++i) polygons[i].point = data[i]; - - return polygons; - } - - voronoi.x = function(_) { - return arguments.length ? (x = _, voronoi) : x; - }; - - voronoi.y = function(_) { - return arguments.length ? (y = _, voronoi) : y; - }; - - voronoi.clipExtent = function(_) { - if (!arguments.length) return clipPolygon && [clipPolygon[0], clipPolygon[2]]; - if (_ == null) clipPolygon = null; - else { - var x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], y2 = +_[1][1]; - clipPolygon = d3.geom.polygon([[x1, y1], [x1, y2], [x2, y2], [x2, y1]]); - } - return voronoi; - }; - - // @deprecated; use clipExtent instead - voronoi.size = function(_) { - if (!arguments.length) return clipPolygon && clipPolygon[2]; - return voronoi.clipExtent(_ && [[0, 0], _]); - }; - - voronoi.links = function(data) { - var points, - graph = data.map(function() { return []; }), - links = [], - fx = d3_functor(x), - fy = d3_functor(y), - d, - i, - n = data.length; - - if (fx === d3_svg_lineX && fy === d3_svg_lineY) points = data; - else for (points = new Array(n), i = 0; i < n; ++i) { - points[i] = [+fx.call(this, d = data[i], i), +fy.call(this, d, i)]; - } - - d3_geom_voronoiTessellate(points, function(e) { - var l = e.region.l.index, - r = e.region.r.index; - if (graph[l][r]) return; - graph[l][r] = graph[r][l] = true; - links.push({source: data[l], target: data[r]}); - }); - - return links; - }; - - voronoi.triangles = function(data) { - if (x === d3_svg_lineX && y === d3_svg_lineY) return d3.geom.delaunay(data); - - var points = new Array(n), - fx = d3_functor(x), - fy = d3_functor(y), - d, - i = -1, - n = data.length; - - while (++i < n) { - (points[i] = [+fx.call(this, d = data[i], i), +fy.call(this, d, i)]).data = d; - } - - return d3.geom.delaunay(points).map(function(triangle) { - return triangle.map(function(point) { - return point.data; - }); - }); - }; - - return voronoi; -}; - -var d3_geom_voronoiOpposite = {l: "r", r: "l"}; - -function d3_geom_voronoiTessellate(points, callback) { - - var Sites = { - list: points - .map(function(v, i) { - return { - index: i, - x: v[0], - y: v[1] - }; - }) - .sort(function(a, b) { - return a.y < b.y ? -1 - : a.y > b.y ? 1 - : a.x < b.x ? -1 - : a.x > b.x ? 1 - : 0; - }), - bottomSite: null - }; - - var EdgeList = { - list: [], - leftEnd: null, - rightEnd: null, - - init: function() { - EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l"); - EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l"); - EdgeList.leftEnd.r = EdgeList.rightEnd; - EdgeList.rightEnd.l = EdgeList.leftEnd; - EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd); - }, - - createHalfEdge: function(edge, side) { - return { - edge: edge, - side: side, - vertex: null, - "l": null, - "r": null - }; - }, - - insert: function(lb, he) { - he.l = lb; - he.r = lb.r; - lb.r.l = he; - lb.r = he; - }, - - leftBound: function(p) { - var he = EdgeList.leftEnd; - do { - he = he.r; - } while (he != EdgeList.rightEnd && Geom.rightOf(he, p)); - he = he.l; - return he; - }, - - del: function(he) { - he.l.r = he.r; - he.r.l = he.l; - he.edge = null; - }, - - right: function(he) { - return he.r; - }, - - left: function(he) { - return he.l; - }, - - leftRegion: function(he) { - return he.edge == null - ? Sites.bottomSite - : he.edge.region[he.side]; - }, - - rightRegion: function(he) { - return he.edge == null - ? Sites.bottomSite - : he.edge.region[d3_geom_voronoiOpposite[he.side]]; - } - }; - - var Geom = { - - bisect: function(s1, s2) { - var newEdge = { - region: {"l": s1, "r": s2}, - ep: {"l": null, "r": null} - }; - - var dx = s2.x - s1.x, - dy = s2.y - s1.y, - adx = dx > 0 ? dx : -dx, - ady = dy > 0 ? dy : -dy; - - newEdge.c = s1.x * dx + s1.y * dy - + (dx * dx + dy * dy) * .5; - - if (adx > ady) { - newEdge.a = 1; - newEdge.b = dy / dx; - newEdge.c /= dx; - } else { - newEdge.b = 1; - newEdge.a = dx / dy; - newEdge.c /= dy; - } - - return newEdge; - }, - - intersect: function(el1, el2) { - var e1 = el1.edge, - e2 = el2.edge; - if (!e1 || !e2 || (e1.region.r == e2.region.r)) { - return null; - } - var d = (e1.a * e2.b) - (e1.b * e2.a); - if (Math.abs(d) < 1e-10) { - return null; - } - var xint = (e1.c * e2.b - e2.c * e1.b) / d, - yint = (e2.c * e1.a - e1.c * e2.a) / d, - e1r = e1.region.r, - e2r = e2.region.r, - el, - e; - if ((e1r.y < e2r.y) || - (e1r.y == e2r.y && e1r.x < e2r.x)) { - el = el1; - e = e1; - } else { - el = el2; - e = e2; - } - var rightOfSite = (xint >= e.region.r.x); - if ((rightOfSite && (el.side === "l")) || - (!rightOfSite && (el.side === "r"))) { - return null; - } - return { - x: xint, - y: yint - }; - }, - - rightOf: function(he, p) { - var e = he.edge, - topsite = e.region.r, - rightOfSite = (p.x > topsite.x); - - if (rightOfSite && (he.side === "l")) { - return 1; - } - if (!rightOfSite && (he.side === "r")) { - return 0; - } - if (e.a === 1) { - var dyp = p.y - topsite.y, - dxp = p.x - topsite.x, - fast = 0, - above = 0; - - if ((!rightOfSite && (e.b < 0)) || - (rightOfSite && (e.b >= 0))) { - above = fast = (dyp >= e.b * dxp); - } else { - above = ((p.x + p.y * e.b) > e.c); - if (e.b < 0) { - above = !above; - } - if (!above) { - fast = 1; - } - } - if (!fast) { - var dxs = topsite.x - e.region.l.x; - above = (e.b * (dxp * dxp - dyp * dyp)) < - (dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b)); - - if (e.b < 0) { - above = !above; - } - } - } else /* e.b == 1 */ { - var yl = e.c - e.a * p.x, - t1 = p.y - yl, - t2 = p.x - topsite.x, - t3 = yl - topsite.y; - - above = (t1 * t1) > (t2 * t2 + t3 * t3); - } - return he.side === "l" ? above : !above; - }, - - endPoint: function(edge, side, site) { - edge.ep[side] = site; - if (!edge.ep[d3_geom_voronoiOpposite[side]]) return; - callback(edge); - }, - - distance: function(s, t) { - var dx = s.x - t.x, - dy = s.y - t.y; - return Math.sqrt(dx * dx + dy * dy); - } - }; - - var EventQueue = { - list: [], - - insert: function(he, site, offset) { - he.vertex = site; - he.ystar = site.y + offset; - for (var i=0, list=EventQueue.list, l=list.length; i next.ystar || - (he.ystar == next.ystar && - site.x > next.vertex.x)) { - continue; - } else { - break; - } - } - list.splice(i, 0, he); - }, - - del: function(he) { - for (var i=0, ls=EventQueue.list, l=ls.length; i top.y) { - temp = bot; - bot = top; - top = temp; - pm = "r"; - } - e = Geom.bisect(bot, top); - bisector = EdgeList.createHalfEdge(e, pm); - EdgeList.insert(llbnd, bisector); - Geom.endPoint(e, d3_geom_voronoiOpposite[pm], v); - p = Geom.intersect(llbnd, bisector); - if (p) { - EventQueue.del(llbnd); - EventQueue.insert(llbnd, p, Geom.distance(p, bot)); - } - p = Geom.intersect(bisector, rrbnd); - if (p) { - EventQueue.insert(bisector, p, Geom.distance(p, bot)); - } - } else { - break; - } - }//end while - - for (lbnd = EdgeList.right(EdgeList.leftEnd); - lbnd != EdgeList.rightEnd; - lbnd = EdgeList.right(lbnd)) { - callback(lbnd.edge); - } -} diff --git a/src/interpolate/array.js b/src/interpolate/array.js deleted file mode 100644 index 33f8f48b58fe89..00000000000000 --- a/src/interpolate/array.js +++ /dev/null @@ -1,19 +0,0 @@ -import "interpolate"; - -d3.interpolateArray = d3_interpolateArray; - -function d3_interpolateArray(a, b) { - var x = [], - c = [], - na = a.length, - nb = b.length, - n0 = Math.min(a.length, b.length), - i; - for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); - for (; i < na; ++i) c[i] = a[i]; - for (; i < nb; ++i) c[i] = b[i]; - return function(t) { - for (i = 0; i < n0; ++i) c[i] = x[i](t); - return c; - }; -} diff --git a/src/interpolate/ease.js b/src/interpolate/ease.js deleted file mode 100644 index edf26f8f182832..00000000000000 --- a/src/interpolate/ease.js +++ /dev/null @@ -1,110 +0,0 @@ -import "../arrays/map"; -import "../core/identity"; -import "../math/trigonometry"; - -var d3_ease_default = function() { return d3_identity; }; - -var d3_ease = d3.map({ - linear: d3_ease_default, - poly: d3_ease_poly, - quad: function() { return d3_ease_quad; }, - cubic: function() { return d3_ease_cubic; }, - sin: function() { return d3_ease_sin; }, - exp: function() { return d3_ease_exp; }, - circle: function() { return d3_ease_circle; }, - elastic: d3_ease_elastic, - back: d3_ease_back, - bounce: function() { return d3_ease_bounce; } -}); - -var d3_ease_mode = d3.map({ - "in": d3_identity, - "out": d3_ease_reverse, - "in-out": d3_ease_reflect, - "out-in": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); } -}); - -d3.ease = function(name) { - var i = name.indexOf("-"), - t = i >= 0 ? name.substring(0, i) : name, - m = i >= 0 ? name.substring(i + 1) : "in"; - t = d3_ease.get(t) || d3_ease_default; - m = d3_ease_mode.get(m) || d3_identity; - return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1)))); -}; - -function d3_ease_clamp(f) { - return function(t) { - return t <= 0 ? 0 : t >= 1 ? 1 : f(t); - }; -} - -function d3_ease_reverse(f) { - return function(t) { - return 1 - f(1 - t); - }; -} - -function d3_ease_reflect(f) { - return function(t) { - return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t))); - }; -} - -function d3_ease_quad(t) { - return t * t; -} - -function d3_ease_cubic(t) { - return t * t * t; -} - -// Optimized clamp(reflect(poly(3))). -function d3_ease_cubicInOut(t) { - if (t <= 0) return 0; - if (t >= 1) return 1; - var t2 = t * t, t3 = t2 * t; - return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); -} - -function d3_ease_poly(e) { - return function(t) { - return Math.pow(t, e); - }; -} - -function d3_ease_sin(t) { - return 1 - Math.cos(t * π / 2); -} - -function d3_ease_exp(t) { - return Math.pow(2, 10 * (t - 1)); -} - -function d3_ease_circle(t) { - return 1 - Math.sqrt(1 - t * t); -} - -function d3_ease_elastic(a, p) { - var s; - if (arguments.length < 2) p = 0.45; - if (arguments.length) s = p / (2 * π) * Math.asin(1 / a); - else a = 1, s = p / 4; - return function(t) { - return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * π / p); - }; -} - -function d3_ease_back(s) { - if (!s) s = 1.70158; - return function(t) { - return t * t * ((s + 1) * t - s); - }; -} - -function d3_ease_bounce(t) { - return t < 1 / 2.75 ? 7.5625 * t * t - : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 - : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 - : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; -} diff --git a/src/interpolate/hcl.js b/src/interpolate/hcl.js deleted file mode 100644 index 4e62591bac59a8..00000000000000 --- a/src/interpolate/hcl.js +++ /dev/null @@ -1,20 +0,0 @@ -import "../color/hcl"; - -d3.interpolateHcl = d3_interpolateHcl; - -function d3_interpolateHcl(a, b) { - a = d3.hcl(a); - b = d3.hcl(b); - var ah = a.h, - ac = a.c, - al = a.l, - bh = b.h - ah, - bc = b.c - ac, - bl = b.l - al; - if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; - else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; // shortest path - return function(t) { - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; - }; -} diff --git a/src/interpolate/hsl.js b/src/interpolate/hsl.js deleted file mode 100644 index 2b8d70f2c594f9..00000000000000 --- a/src/interpolate/hsl.js +++ /dev/null @@ -1,20 +0,0 @@ -import "../color/hsl"; - -d3.interpolateHsl = d3_interpolateHsl; - -function d3_interpolateHsl(a, b) { - a = d3.hsl(a); - b = d3.hsl(b); - var ah = a.h, - as = a.s, - al = a.l, - bh = b.h - ah, - bs = b.s - as, - bl = b.l - al; - if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; - else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; // shortest path - return function(t) { - return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; - }; -} diff --git a/src/interpolate/index.js b/src/interpolate/index.js deleted file mode 100644 index ed6c5020a74d82..00000000000000 --- a/src/interpolate/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import "array"; -import "ease"; -import "hcl"; -import "hsl"; -import "interpolate"; -import "lab"; -import "number"; -import "object"; -import "rgb"; -import "round"; -import "string"; -import "transform"; -import "uninterpolate"; -import "zoom"; diff --git a/src/interpolate/interpolate.js b/src/interpolate/interpolate.js deleted file mode 100644 index 09b11d714bc9c5..00000000000000 --- a/src/interpolate/interpolate.js +++ /dev/null @@ -1,25 +0,0 @@ -import "../color/color"; -import "../color/rgb"; -import "rgb"; -import "object"; -import "array"; -import "number"; -import "string"; - -d3.interpolate = d3_interpolate; - -function d3_interpolate(a, b) { - var i = d3.interpolators.length, f; - while (--i >= 0 && !(f = d3.interpolators[i](a, b))); - return f; -} - -d3.interpolators = [ - function(a, b) { - var t = typeof b; - return (t === "string" ? (d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString) - : b instanceof d3_Color ? d3_interpolateRgb - : t === "object" ? (Array.isArray(b) ? d3_interpolateArray : d3_interpolateObject) - : d3_interpolateNumber)(a, b); - } -]; diff --git a/src/interpolate/lab.js b/src/interpolate/lab.js deleted file mode 100644 index 6b46c044885e55..00000000000000 --- a/src/interpolate/lab.js +++ /dev/null @@ -1,17 +0,0 @@ -import "../color/lab"; - -d3.interpolateLab = d3_interpolateLab; - -function d3_interpolateLab(a, b) { - a = d3.lab(a); - b = d3.lab(b); - var al = a.l, - aa = a.a, - ab = a.b, - bl = b.l - al, - ba = b.a - aa, - bb = b.b - ab; - return function(t) { - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; - }; -} diff --git a/src/interpolate/number.js b/src/interpolate/number.js deleted file mode 100644 index 353b0942abc59d..00000000000000 --- a/src/interpolate/number.js +++ /dev/null @@ -1,6 +0,0 @@ -d3.interpolateNumber = d3_interpolateNumber; - -function d3_interpolateNumber(a, b) { - b -= a = +a; - return function(t) { return a + b * t; }; -} diff --git a/src/interpolate/object.js b/src/interpolate/object.js deleted file mode 100644 index a3f863af208f30..00000000000000 --- a/src/interpolate/object.js +++ /dev/null @@ -1,25 +0,0 @@ -import "interpolate"; - -d3.interpolateObject = d3_interpolateObject; - -function d3_interpolateObject(a, b) { - var i = {}, - c = {}, - k; - for (k in a) { - if (k in b) { - i[k] = d3_interpolate(a[k], b[k]); - } else { - c[k] = a[k]; - } - } - for (k in b) { - if (!(k in a)) { - c[k] = b[k]; - } - } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; -} diff --git a/src/interpolate/rgb.js b/src/interpolate/rgb.js deleted file mode 100644 index f4944d2fe6cfd7..00000000000000 --- a/src/interpolate/rgb.js +++ /dev/null @@ -1,20 +0,0 @@ -import "../color/rgb"; - -d3.interpolateRgb = d3_interpolateRgb; - -function d3_interpolateRgb(a, b) { - a = d3.rgb(a); - b = d3.rgb(b); - var ar = a.r, - ag = a.g, - ab = a.b, - br = b.r - ar, - bg = b.g - ag, - bb = b.b - ab; - return function(t) { - return "#" - + d3_rgb_hex(Math.round(ar + br * t)) - + d3_rgb_hex(Math.round(ag + bg * t)) - + d3_rgb_hex(Math.round(ab + bb * t)); - }; -} diff --git a/src/interpolate/round.js b/src/interpolate/round.js deleted file mode 100644 index 8e8797dfdf9bdb..00000000000000 --- a/src/interpolate/round.js +++ /dev/null @@ -1,6 +0,0 @@ -d3.interpolateRound = d3_interpolateRound; - -function d3_interpolateRound(a, b) { - b -= a; - return function(t) { return Math.round(a + b * t); }; -} diff --git a/src/interpolate/string.js b/src/interpolate/string.js deleted file mode 100644 index 843870b3a25cf7..00000000000000 --- a/src/interpolate/string.js +++ /dev/null @@ -1,88 +0,0 @@ -import "number"; - -d3.interpolateString = d3_interpolateString; - -function d3_interpolateString(a, b) { - var m, // current match - i, // current index - j, // current index (for coalescing) - s0 = 0, // start index of current string prefix - s1 = 0, // end index of current string prefix - s = [], // string constants and placeholders - q = [], // number interpolators - n, // q.length - o; - - // Coerce inputs to strings. - a = a + "", b = b + ""; - - // Reset our regular expression! - d3_interpolate_number.lastIndex = 0; - - // Find all numbers in b. - for (i = 0; m = d3_interpolate_number.exec(b); ++i) { - if (m.index) s.push(b.substring(s0, s1 = m.index)); - q.push({i: s.length, x: m[0]}); - s.push(null); - s0 = d3_interpolate_number.lastIndex; - } - if (s0 < b.length) s.push(b.substring(s0)); - - // Find all numbers in a. - for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { - o = q[i]; - if (o.x == m[0]) { // The numbers match, so coalesce. - if (o.i) { - if (s[o.i + 1] == null) { // This match is followed by another number. - s[o.i - 1] += o.x; - s.splice(o.i, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } else { // This match is followed by a string, so coalesce twice. - s[o.i - 1] += o.x + s[o.i + 1]; - s.splice(o.i, 2); - for (j = i + 1; j < n; ++j) q[j].i -= 2; - } - } else { - if (s[o.i + 1] == null) { // This match is followed by another number. - s[o.i] = o.x; - } else { // This match is followed by a string, so coalesce twice. - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } - } - q.splice(i, 1); - n--; - i--; - } else { - o.x = d3_interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); - } - } - - // Remove any numbers in b not found in a. - while (i < n) { - o = q.pop(); - if (s[o.i + 1] == null) { // This match is followed by another number. - s[o.i] = o.x; - } else { // This match is followed by a string, so coalesce twice. - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - } - n--; - } - - // Special optimization for only a single match. - if (s.length === 1) { - return s[0] == null - ? (o = q[0].x, function(t) { return o(t) + ""; }) - : function() { return b; }; - } - - // Otherwise, interpolate each of the numbers and rejoin the string. - return function(t) { - for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; -} - -var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; diff --git a/src/interpolate/transform.js b/src/interpolate/transform.js deleted file mode 100644 index 17a19cbaf95aca..00000000000000 --- a/src/interpolate/transform.js +++ /dev/null @@ -1,56 +0,0 @@ -import "../math/transform"; -import "number"; - -d3.interpolateTransform = d3_interpolateTransform; - -function d3_interpolateTransform(a, b) { - var s = [], // string constants and placeholders - q = [], // number interpolators - n, - A = d3.transform(a), - B = d3.transform(b), - ta = A.translate, - tb = B.translate, - ra = A.rotate, - rb = B.rotate, - wa = A.skew, - wb = B.skew, - ka = A.scale, - kb = B.scale; - - if (ta[0] != tb[0] || ta[1] != tb[1]) { - s.push("translate(", null, ",", null, ")"); - q.push({i: 1, x: d3_interpolateNumber(ta[0], tb[0])}, {i: 3, x: d3_interpolateNumber(ta[1], tb[1])}); - } else if (tb[0] || tb[1]) { - s.push("translate(" + tb + ")"); - } else { - s.push(""); - } - - if (ra != rb) { - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; // shortest path - q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3_interpolateNumber(ra, rb)}); - } else if (rb) { - s.push(s.pop() + "rotate(" + rb + ")"); - } - - if (wa != wb) { - q.push({i: s.push(s.pop() + "skewX(", null, ")") - 2, x: d3_interpolateNumber(wa, wb)}); - } else if (wb) { - s.push(s.pop() + "skewX(" + wb + ")"); - } - - if (ka[0] != kb[0] || ka[1] != kb[1]) { - n = s.push(s.pop() + "scale(", null, ",", null, ")"); - q.push({i: n - 4, x: d3_interpolateNumber(ka[0], kb[0])}, {i: n - 2, x: d3_interpolateNumber(ka[1], kb[1])}); - } else if (kb[0] != 1 || kb[1] != 1) { - s.push(s.pop() + "scale(" + kb + ")"); - } - - n = q.length; - return function(t) { - var i = -1, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; -} diff --git a/src/interpolate/uninterpolate.js b/src/interpolate/uninterpolate.js deleted file mode 100644 index 4337381f8403a6..00000000000000 --- a/src/interpolate/uninterpolate.js +++ /dev/null @@ -1,9 +0,0 @@ -function d3_uninterpolateNumber(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { return (x - a) * b; }; -} - -function d3_uninterpolateClamp(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); }; -} diff --git a/src/interpolate/zoom.js b/src/interpolate/zoom.js deleted file mode 100644 index ae6b5c7e153d2b..00000000000000 --- a/src/interpolate/zoom.js +++ /dev/null @@ -1,47 +0,0 @@ -import "../math/trigonometry"; - -var ρ = Math.SQRT2, - ρ2 = 2, - ρ4 = 4; - -// p0 = [ux0, uy0, w0] -// p1 = [ux1, uy1, w1] -d3.interpolateZoom = function(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], - ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; - - var dx = ux1 - ux0, - dy = uy1 - uy0, - d2 = dx * dx + dy * dy, - d1 = Math.sqrt(d2), - b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), - b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), - r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), - r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), - dr = r1 - r0, - S = (dr || Math.log(w1 / w0)) / ρ; - - function interpolate(t) { - var s = t * S; - if (dr) { - // General case. - var coshr0 = d3_cosh(r0), - u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); - return [ - ux0 + u * dx, - uy0 + u * dy, - w0 * coshr0 / d3_cosh(ρ * s + r0) - ]; - } - // Special case for u0 ~= u1. - return [ - ux0 + t * dx, - uy0 + t * dy, - w0 * Math.exp(ρ * s) - ]; - } - - interpolate.duration = S * 1000; - - return interpolate; -}; diff --git a/src/layout/bundle.js b/src/layout/bundle.js deleted file mode 100644 index 3f3024433cd2e9..00000000000000 --- a/src/layout/bundle.js +++ /dev/null @@ -1,59 +0,0 @@ -import "layout"; - -// Implements hierarchical edge bundling using Holten's algorithm. For each -// input link, a path is computed that travels through the tree, up the parent -// hierarchy to the least common ancestor, and then back down to the destination -// node. Each path is simply an array of nodes. -d3.layout.bundle = function() { - return function(links) { - var paths = [], - i = -1, - n = links.length; - while (++i < n) paths.push(d3_layout_bundlePath(links[i])); - return paths; - }; -}; - -function d3_layout_bundlePath(link) { - var start = link.source, - end = link.target, - lca = d3_layout_bundleLeastCommonAncestor(start, end), - points = [start]; - while (start !== lca) { - start = start.parent; - points.push(start); - } - var k = points.length; - while (end !== lca) { - points.splice(k, 0, end); - end = end.parent; - } - return points; -} - -function d3_layout_bundleAncestors(node) { - var ancestors = [], - parent = node.parent; - while (parent != null) { - ancestors.push(node); - node = parent; - parent = parent.parent; - } - ancestors.push(node); - return ancestors; -} - -function d3_layout_bundleLeastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = d3_layout_bundleAncestors(a), - bNodes = d3_layout_bundleAncestors(b), - aNode = aNodes.pop(), - bNode = bNodes.pop(), - sharedNode = null; - while (aNode === bNode) { - sharedNode = aNode; - aNode = aNodes.pop(); - bNode = bNodes.pop(); - } - return sharedNode; -} diff --git a/src/layout/chord.js b/src/layout/chord.js deleted file mode 100644 index 7605dac8bb8b44..00000000000000 --- a/src/layout/chord.js +++ /dev/null @@ -1,157 +0,0 @@ -import "../arrays/range"; -import "../math/trigonometry"; -import "layout"; - -d3.layout.chord = function() { - var chord = {}, - chords, - groups, - matrix, - n, - padding = 0, - sortGroups, - sortSubgroups, - sortChords; - - function relayout() { - var subgroups = {}, - groupSums = [], - groupIndex = d3.range(n), - subgroupIndex = [], - k, - x, - x0, - i, - j; - - chords = []; - groups = []; - - // Compute the sum. - k = 0, i = -1; while (++i < n) { - x = 0, j = -1; while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(d3.range(n)); - k += x; - } - - // Sort groups… - if (sortGroups) { - groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); - } - - // Sort subgroups… - if (sortSubgroups) { - subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); - } - - // Convert the sum to scaling factor for [0, 2pi]. - // TODO Allow start and end angle to be specified. - // TODO Allow padding to be specified as percentage? - k = (2 * π - padding * n) / k; - - // Compute the start and end angle for each group and subgroup. - // Note: Opera has a bug reordering object literal properties! - x = 0, i = -1; while (++i < n) { - x0 = x, j = -1; while (++j < n) { - var di = groupIndex[i], - dj = subgroupIndex[di][j], - v = matrix[di][dj], - a0 = x, - a1 = x += v * k; - subgroups[di + "-" + dj] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: (x - x0) / k - }; - x += padding; - } - - // Generate chords for each (non-empty) subgroup-subgroup link. - i = -1; while (++i < n) { - j = i - 1; while (++j < n) { - var source = subgroups[i + "-" + j], - target = subgroups[j + "-" + i]; - if (source.value || target.value) { - chords.push(source.value < target.value - ? {source: target, target: source} - : {source: source, target: target}); - } - } - } - - if (sortChords) resort(); - } - - function resort() { - chords.sort(function(a, b) { - return sortChords( - (a.source.value + a.target.value) / 2, - (b.source.value + b.target.value) / 2); - }); - } - - chord.matrix = function(x) { - if (!arguments.length) return matrix; - n = (matrix = x) && matrix.length; - chords = groups = null; - return chord; - }; - - chord.padding = function(x) { - if (!arguments.length) return padding; - padding = x; - chords = groups = null; - return chord; - }; - - chord.sortGroups = function(x) { - if (!arguments.length) return sortGroups; - sortGroups = x; - chords = groups = null; - return chord; - }; - - chord.sortSubgroups = function(x) { - if (!arguments.length) return sortSubgroups; - sortSubgroups = x; - chords = null; - return chord; - }; - - chord.sortChords = function(x) { - if (!arguments.length) return sortChords; - sortChords = x; - if (chords) resort(); - return chord; - }; - - chord.chords = function() { - if (!chords) relayout(); - return chords; - }; - - chord.groups = function() { - if (!groups) relayout(); - return groups; - }; - - return chord; -}; diff --git a/src/layout/cluster.js b/src/layout/cluster.js deleted file mode 100644 index c5a37b5ad393fe..00000000000000 --- a/src/layout/cluster.js +++ /dev/null @@ -1,92 +0,0 @@ -import "../arrays/max"; -import "layout"; -import "hierarchy"; -import "tree"; - -// Implements a hierarchical layout using the cluster (or dendrogram) -// algorithm. -d3.layout.cluster = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), - separation = d3_layout_treeSeparation, - size = [1, 1], // width, height - nodeSize = false; - - function cluster(d, i) { - var nodes = hierarchy.call(this, d, i), - root = nodes[0], - previousNode, - x = 0; - - // First walk, computing the initial x & y values. - d3_layout_treeVisitAfter(root, function(node) { - var children = node.children; - if (children && children.length) { - node.x = d3_layout_clusterX(children); - node.y = d3_layout_clusterY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; - } - }); - - // Compute the left-most, right-most, and depth-most nodes for extents. - var left = d3_layout_clusterLeft(root), - right = d3_layout_clusterRight(root), - x0 = left.x - separation(left, right) / 2, - x1 = right.x + separation(right, left) / 2; - - // Second walk, normalizing x & y to the desired size. - d3_layout_treeVisitAfter(root, nodeSize ? function(node) { - node.x = (node.x - root.x) * size[0]; - node.y = (root.y - node.y) * size[1]; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; - }); - - return nodes; - } - - cluster.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return cluster; - }; - - cluster.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return cluster; - }; - - cluster.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return cluster; - }; - - return d3_layout_hierarchyRebind(cluster, hierarchy); -}; - -function d3_layout_clusterY(children) { - return 1 + d3.max(children, function(child) { - return child.y; - }); -} - -function d3_layout_clusterX(children) { - return children.reduce(function(x, child) { - return x + child.x; - }, 0) / children.length; -} - -function d3_layout_clusterLeft(node) { - var children = node.children; - return children && children.length ? d3_layout_clusterLeft(children[0]) : node; -} - -function d3_layout_clusterRight(node) { - var children = node.children, n; - return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; -} diff --git a/src/layout/force.js b/src/layout/force.js deleted file mode 100644 index 89f41139dfd770..00000000000000 --- a/src/layout/force.js +++ /dev/null @@ -1,359 +0,0 @@ -import "../behavior/drag"; -import "../core/identity"; -import "../core/rebind"; -import "../event/event"; -import "../event/dispatch"; -import "../event/timer"; -import "../geom/quadtree"; -import "layout"; - -// A rudimentary force layout using Gauss-Seidel. -d3.layout.force = function() { - var force = {}, - event = d3.dispatch("start", "tick", "end"), - size = [1, 1], - drag, - alpha, - friction = .9, - linkDistance = d3_layout_forceLinkDistance, - linkStrength = d3_layout_forceLinkStrength, - charge = -30, - gravity = .1, - theta = .8, - nodes = [], - links = [], - distances, - strengths, - charges; - - function repulse(node) { - return function(quad, x1, _, x2) { - if (quad.point !== node) { - var dx = quad.cx - node.x, - dy = quad.cy - node.y, - dn = 1 / Math.sqrt(dx * dx + dy * dy); - - /* Barnes-Hut criterion. */ - if ((x2 - x1) * dn < theta) { - var k = quad.charge * dn * dn; - node.px -= dx * k; - node.py -= dy * k; - return true; - } - - if (quad.point && isFinite(dn)) { - var k = quad.pointCharge * dn * dn; - node.px -= dx * k; - node.py -= dy * k; - } - } - return !quad.charge; - }; - } - - force.tick = function() { - // simulated annealing, basically - if ((alpha *= .99) < .005) { - event.end({type: "end", alpha: alpha = 0}); - return true; - } - - var n = nodes.length, - m = links.length, - q, - i, // current index - o, // current object - s, // current source - t, // current target - l, // current distance - k, // current force - x, // x-distance - y; // y-distance - - // gauss-seidel relaxation for links - for (i = 0; i < m; ++i) { - o = links[i]; - s = o.source; - t = o.target; - x = t.x - s.x; - y = t.y - s.y; - if (l = (x * x + y * y)) { - l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; - x *= l; - y *= l; - t.x -= x * (k = s.weight / (t.weight + s.weight)); - t.y -= y * k; - s.x += x * (k = 1 - k); - s.y += y * k; - } - } - - // apply gravity forces - if (k = alpha * gravity) { - x = size[0] / 2; - y = size[1] / 2; - i = -1; if (k) while (++i < n) { - o = nodes[i]; - o.x += (x - o.x) * k; - o.y += (y - o.y) * k; - } - } - - // compute quadtree center of mass and apply charge forces - if (charge) { - d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); - i = -1; while (++i < n) { - if (!(o = nodes[i]).fixed) { - q.visit(repulse(o)); - } - } - } - - // position verlet integration - i = -1; while (++i < n) { - o = nodes[i]; - if (o.fixed) { - o.x = o.px; - o.y = o.py; - } else { - o.x -= (o.px - (o.px = o.x)) * friction; - o.y -= (o.py - (o.py = o.y)) * friction; - } - } - - event.tick({type: "tick", alpha: alpha}); - }; - - force.nodes = function(x) { - if (!arguments.length) return nodes; - nodes = x; - return force; - }; - - force.links = function(x) { - if (!arguments.length) return links; - links = x; - return force; - }; - - force.size = function(x) { - if (!arguments.length) return size; - size = x; - return force; - }; - - force.linkDistance = function(x) { - if (!arguments.length) return linkDistance; - linkDistance = typeof x === "function" ? x : +x; - return force; - }; - - // For backwards-compatibility. - force.distance = force.linkDistance; - - force.linkStrength = function(x) { - if (!arguments.length) return linkStrength; - linkStrength = typeof x === "function" ? x : +x; - return force; - }; - - force.friction = function(x) { - if (!arguments.length) return friction; - friction = +x; - return force; - }; - - force.charge = function(x) { - if (!arguments.length) return charge; - charge = typeof x === "function" ? x : +x; - return force; - }; - - force.gravity = function(x) { - if (!arguments.length) return gravity; - gravity = +x; - return force; - }; - - force.theta = function(x) { - if (!arguments.length) return theta; - theta = +x; - return force; - }; - - force.alpha = function(x) { - if (!arguments.length) return alpha; - - x = +x; - if (alpha) { // if we're already running - if (x > 0) alpha = x; // we might keep it hot - else alpha = 0; // or, next tick will dispatch "end" - } else if (x > 0) { // otherwise, fire it up! - event.start({type: "start", alpha: alpha = x}); - d3.timer(force.tick); - } - - return force; - }; - - force.start = function() { - var i, - j, - n = nodes.length, - m = links.length, - w = size[0], - h = size[1], - neighbors, - o; - - for (i = 0; i < n; ++i) { - (o = nodes[i]).index = i; - o.weight = 0; - } - - for (i = 0; i < m; ++i) { - o = links[i]; - if (typeof o.source == "number") o.source = nodes[o.source]; - if (typeof o.target == "number") o.target = nodes[o.target]; - ++o.source.weight; - ++o.target.weight; - } - - for (i = 0; i < n; ++i) { - o = nodes[i]; - if (isNaN(o.x)) o.x = position("x", w); - if (isNaN(o.y)) o.y = position("y", h); - if (isNaN(o.px)) o.px = o.x; - if (isNaN(o.py)) o.py = o.y; - } - - distances = []; - if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); - else for (i = 0; i < m; ++i) distances[i] = linkDistance; - - strengths = []; - if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); - else for (i = 0; i < m; ++i) strengths[i] = linkStrength; - - charges = []; - if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); - else for (i = 0; i < n; ++i) charges[i] = charge; - - // initialize node position based on first neighbor - function position(dimension, size) { - var neighbors = neighbor(i), - j = -1, - m = neighbors.length, - x; - while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x; - return Math.random() * size; - } - - // initialize neighbors lazily - function neighbor() { - if (!neighbors) { - neighbors = []; - for (j = 0; j < n; ++j) { - neighbors[j] = []; - } - for (j = 0; j < m; ++j) { - var o = links[j]; - neighbors[o.source.index].push(o.target); - neighbors[o.target.index].push(o.source); - } - } - return neighbors[i]; - } - - return force.resume(); - }; - - force.resume = function() { - return force.alpha(.1); - }; - - force.stop = function() { - return force.alpha(0); - }; - - // use `node.call(force.drag)` to make nodes draggable - force.drag = function() { - if (!drag) drag = d3.behavior.drag() - .origin(d3_identity) - .on("dragstart.force", d3_layout_forceDragstart) - .on("drag.force", dragmove) - .on("dragend.force", d3_layout_forceDragend); - - if (!arguments.length) return drag; - - this.on("mouseover.force", d3_layout_forceMouseover) - .on("mouseout.force", d3_layout_forceMouseout) - .call(drag); - }; - - function dragmove(d) { - d.px = d3.event.x, d.py = d3.event.y; - force.resume(); // restart annealing - } - - return d3.rebind(force, event, "on"); -}; - -// The fixed property has three bits: -// Bit 1 can be set externally (e.g., d.fixed = true) and show persist. -// Bit 2 stores the dragging state, from mousedown to mouseup. -// Bit 3 stores the hover state, from mouseover to mouseout. -// Dragend is a special case: it also clears the hover state. - -function d3_layout_forceDragstart(d) { - d.fixed |= 2; // set bit 2 -} - -function d3_layout_forceDragend(d) { - d.fixed &= ~6; // unset bits 2 and 3 -} - -function d3_layout_forceMouseover(d) { - d.fixed |= 4; // set bit 3 - d.px = d.x, d.py = d.y; // set velocity to zero -} - -function d3_layout_forceMouseout(d) { - d.fixed &= ~4; // unset bit 3 -} - -function d3_layout_forceAccumulate(quad, alpha, charges) { - var cx = 0, - cy = 0; - quad.charge = 0; - if (!quad.leaf) { - var nodes = quad.nodes, - n = nodes.length, - i = -1, - c; - while (++i < n) { - c = nodes[i]; - if (c == null) continue; - d3_layout_forceAccumulate(c, alpha, charges); - quad.charge += c.charge; - cx += c.charge * c.cx; - cy += c.charge * c.cy; - } - } - if (quad.point) { - // jitter internal nodes that are coincident - if (!quad.leaf) { - quad.point.x += Math.random() - .5; - quad.point.y += Math.random() - .5; - } - var k = alpha * charges[quad.point.index]; - quad.charge += quad.pointCharge = k; - cx += k * quad.point.x; - cy += k * quad.point.y; - } - quad.cx = cx / quad.charge; - quad.cy = cy / quad.charge; -} - -var d3_layout_forceLinkDistance = 20, - d3_layout_forceLinkStrength = 1; diff --git a/src/layout/hierarchy.js b/src/layout/hierarchy.js deleted file mode 100644 index 7dd5aa2c6b9ae1..00000000000000 --- a/src/layout/hierarchy.js +++ /dev/null @@ -1,116 +0,0 @@ -import "../arrays/merge"; -import "../core/rebind"; -import "layout"; - -d3.layout.hierarchy = function() { - var sort = d3_layout_hierarchySort, - children = d3_layout_hierarchyChildren, - value = d3_layout_hierarchyValue; - - // Recursively compute the node depth and value. - // Also converts to a standard hierarchy structure. - function recurse(node, depth, nodes) { - var childs = children.call(hierarchy, node, depth); - node.depth = depth; - nodes.push(node); - if (childs && (n = childs.length)) { - var i = -1, - n, - c = node.children = [], - v = 0, - j = depth + 1, - d; - while (++i < n) { - d = recurse(childs[i], j, nodes); - d.parent = node; - c.push(d); - v += d.value; - } - if (sort) c.sort(sort); - if (value) node.value = v; - } else if (value) { - node.value = +value.call(hierarchy, node, depth) || 0; - } - return node; - } - - // Recursively re-evaluates the node value. - function revalue(node, depth) { - var children = node.children, - v = 0; - if (children && (n = children.length)) { - var i = -1, - n, - j = depth + 1; - while (++i < n) v += revalue(children[i], j); - } else if (value) { - v = +value.call(hierarchy, node, depth) || 0; - } - if (value) node.value = v; - return v; - } - - function hierarchy(d) { - var nodes = []; - recurse(d, 0, nodes); - return nodes; - } - - hierarchy.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return hierarchy; - }; - - hierarchy.children = function(x) { - if (!arguments.length) return children; - children = x; - return hierarchy; - }; - - hierarchy.value = function(x) { - if (!arguments.length) return value; - value = x; - return hierarchy; - }; - - // Re-evaluates the `value` property for the specified hierarchy. - hierarchy.revalue = function(root) { - revalue(root, 0); - return root; - }; - - return hierarchy; -}; - -// A method assignment helper for hierarchy subclasses. -function d3_layout_hierarchyRebind(object, hierarchy) { - d3.rebind(object, hierarchy, "sort", "children", "value"); - - // Add an alias for nodes and links, for convenience. - object.nodes = object; - object.links = d3_layout_hierarchyLinks; - - return object; -} - -function d3_layout_hierarchyChildren(d) { - return d.children; -} - -function d3_layout_hierarchyValue(d) { - return d.value; -} - -function d3_layout_hierarchySort(a, b) { - return b.value - a.value; -} - -// Returns an array source+target objects for the specified nodes. -function d3_layout_hierarchyLinks(nodes) { - return d3.merge(nodes.map(function(parent) { - return (parent.children || []).map(function(child) { - return {source: parent, target: child}; - }); - })); -} diff --git a/src/layout/histogram.js b/src/layout/histogram.js deleted file mode 100644 index 4105d9bb503ade..00000000000000 --- a/src/layout/histogram.js +++ /dev/null @@ -1,110 +0,0 @@ -import "../arrays/bisect"; -import "../arrays/min"; -import "../arrays/max"; -import "../core/functor"; -import "layout"; - -d3.layout.histogram = function() { - var frequency = true, - valuer = Number, - ranger = d3_layout_histogramRange, - binner = d3_layout_histogramBinSturges; - - function histogram(data, i) { - var bins = [], - values = data.map(valuer, this), - range = ranger.call(this, values, i), - thresholds = binner.call(this, range, values, i), - bin, - i = -1, - n = values.length, - m = thresholds.length - 1, - k = frequency ? 1 : 1 / n, - x; - - // Initialize the bins. - while (++i < m) { - bin = bins[i] = []; - bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); - bin.y = 0; - } - - // Fill the bins, ignoring values outside the range. - if (m > 0) { - i = -1; while(++i < n) { - x = values[i]; - if (x >= range[0] && x <= range[1]) { - bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; - bin.y += k; - bin.push(data[i]); - } - } - } - - return bins; - } - - // Specifies how to extract a value from the associated data. The default - // value function is `Number`, which is equivalent to the identity function. - histogram.value = function(x) { - if (!arguments.length) return valuer; - valuer = x; - return histogram; - }; - - // Specifies the range of the histogram. Values outside the specified range - // will be ignored. The argument `x` may be specified either as a two-element - // array representing the minimum and maximum value of the range, or as a - // function that returns the range given the array of values and the current - // index `i`. The default range is the extent (minimum and maximum) of the - // values. - histogram.range = function(x) { - if (!arguments.length) return ranger; - ranger = d3_functor(x); - return histogram; - }; - - // Specifies how to bin values in the histogram. The argument `x` may be - // specified as a number, in which case the range of values will be split - // uniformly into the given number of bins. Or, `x` may be an array of - // threshold values, defining the bins; the specified array must contain the - // rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x` - // may be a function which is evaluated, being passed the range, the array of - // values, and the current index `i`, returning an array of thresholds. The - // default bin function will divide the values into uniform bins using - // Sturges' formula. - histogram.bins = function(x) { - if (!arguments.length) return binner; - binner = typeof x === "number" - ? function(range) { return d3_layout_histogramBinFixed(range, x); } - : d3_functor(x); - return histogram; - }; - - // Specifies whether the histogram's `y` value is a count (frequency) or a - // probability (density). The default value is true. - histogram.frequency = function(x) { - if (!arguments.length) return frequency; - frequency = !!x; - return histogram; - }; - - return histogram; -}; - -function d3_layout_histogramBinSturges(range, values) { - return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); -} - -function d3_layout_histogramBinFixed(range, n) { - var x = -1, - b = +range[0], - m = (range[1] - b) / n, - f = []; - while (++x <= n) f[x] = m * x + b; - return f; -} - -function d3_layout_histogramRange(values) { - return [d3.min(values), d3.max(values)]; -} diff --git a/src/layout/index.js b/src/layout/index.js deleted file mode 100644 index 9c203f3d3d1963..00000000000000 --- a/src/layout/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import "layout"; -import "bundle"; -import "chord"; -import "force"; -import "partition"; -import "pie"; -import "stack"; -import "histogram"; -import "hierarchy"; -import "pack"; -import "cluster"; -import "tree"; -import "treemap"; diff --git a/src/layout/layout.js b/src/layout/layout.js deleted file mode 100644 index 3bcbccefe6c457..00000000000000 --- a/src/layout/layout.js +++ /dev/null @@ -1 +0,0 @@ -d3.layout = {}; diff --git a/src/layout/pack.js b/src/layout/pack.js deleted file mode 100644 index 739b74b9e4cc51..00000000000000 --- a/src/layout/pack.js +++ /dev/null @@ -1,212 +0,0 @@ -import "layout"; -import "hierarchy"; -import "tree"; - -d3.layout.pack = function() { - var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), - padding = 0, - size = [1, 1], - radius; - - function pack(d, i) { - var nodes = hierarchy.call(this, d, i), - root = nodes[0], - w = size[0], - h = size[1], - r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { return radius; }; - - // Recursively compute the layout. - root.x = root.y = 0; - d3_layout_treeVisitAfter(root, function(d) { d.r = +r(d.value); }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - - // When padding, recompute the layout using scaled padding. - if (padding) { - var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; - d3_layout_treeVisitAfter(root, function(d) { d.r += dr; }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - d3_layout_treeVisitAfter(root, function(d) { d.r -= dr; }); - } - - // Translate and scale the layout to fit the requested size. - d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); - - return nodes; - } - - pack.size = function(_) { - if (!arguments.length) return size; - size = _; - return pack; - }; - - pack.radius = function(_) { - if (!arguments.length) return radius; - radius = _ == null || typeof _ === "function" ? _ : +_; - return pack; - }; - - pack.padding = function(_) { - if (!arguments.length) return padding; - padding = +_; - return pack; - }; - - return d3_layout_hierarchyRebind(pack, hierarchy); -}; - -function d3_layout_packSort(a, b) { - return a.value - b.value; -} - -function d3_layout_packInsert(a, b) { - var c = a._pack_next; - a._pack_next = b; - b._pack_prev = a; - b._pack_next = c; - c._pack_prev = b; -} - -function d3_layout_packSplice(a, b) { - a._pack_next = b; - b._pack_prev = a; -} - -function d3_layout_packIntersects(a, b) { - var dx = b.x - a.x, - dy = b.y - a.y, - dr = a.r + b.r; - return .999 * dr * dr > dx * dx + dy * dy; // relative error within epsilon -} - -function d3_layout_packSiblings(node) { - if (!(nodes = node.children) || !(n = nodes.length)) return; - - var nodes, - xMin = Infinity, - xMax = -Infinity, - yMin = Infinity, - yMax = -Infinity, - a, b, c, i, j, k, n; - - function bound(node) { - xMin = Math.min(node.x - node.r, xMin); - xMax = Math.max(node.x + node.r, xMax); - yMin = Math.min(node.y - node.r, yMin); - yMax = Math.max(node.y + node.r, yMax); - } - - // Create node links. - nodes.forEach(d3_layout_packLink); - - // Create first node. - a = nodes[0]; - a.x = -a.r; - a.y = 0; - bound(a); - - // Create second node. - if (n > 1) { - b = nodes[1]; - b.x = b.r; - b.y = 0; - bound(b); - - // Create third node and build chain. - if (n > 2) { - c = nodes[2]; - d3_layout_packPlace(a, b, c); - bound(c); - d3_layout_packInsert(a, c); - a._pack_prev = c; - d3_layout_packInsert(c, b); - b = a._pack_next; - - // Now iterate through the rest. - for (i = 3; i < n; i++) { - d3_layout_packPlace(a, b, c = nodes[i]); - - // Search for the closest intersection. - var isect = 0, s1 = 1, s2 = 1; - for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { - if (d3_layout_packIntersects(j, c)) { - isect = 1; - break; - } - } - if (isect == 1) { - for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { - if (d3_layout_packIntersects(k, c)) { - break; - } - } - } - - // Update node chain. - if (isect) { - if (s1 < s2 || (s1 == s2 && b.r < a.r)) d3_layout_packSplice(a, b = j); - else d3_layout_packSplice(a = k, b); - i--; - } else { - d3_layout_packInsert(a, c); - b = c; - bound(c); - } - } - } - } - - // Re-center the circles and compute the encompassing radius. - var cx = (xMin + xMax) / 2, - cy = (yMin + yMax) / 2, - cr = 0; - for (i = 0; i < n; i++) { - c = nodes[i]; - c.x -= cx; - c.y -= cy; - cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); - } - node.r = cr; - - // Remove node links. - nodes.forEach(d3_layout_packUnlink); -} - -function d3_layout_packLink(node) { - node._pack_next = node._pack_prev = node; -} - -function d3_layout_packUnlink(node) { - delete node._pack_next; - delete node._pack_prev; -} - -function d3_layout_packTransform(node, x, y, k) { - var children = node.children; - node.x = (x += k * node.x); - node.y = (y += k * node.y); - node.r *= k; - if (children) { - var i = -1, n = children.length; - while (++i < n) d3_layout_packTransform(children[i], x, y, k); - } -} - -function d3_layout_packPlace(a, b, c) { - var db = a.r + c.r, - dx = b.x - a.x, - dy = b.y - a.y; - if (db && (dx || dy)) { - var da = b.r + c.r, - dc = dx * dx + dy * dy; - da *= da; - db *= db; - var x = .5 + (db - da) / (2 * dc), - y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); - c.x = a.x + x * dx + y * dy; - c.y = a.y + x * dy - y * dx; - } else { - c.x = a.x + db; - c.y = a.y; - } -} diff --git a/src/layout/partition.js b/src/layout/partition.js deleted file mode 100644 index 581fd052377c00..00000000000000 --- a/src/layout/partition.js +++ /dev/null @@ -1,51 +0,0 @@ -import "layout"; -import "hierarchy"; - -d3.layout.partition = function() { - var hierarchy = d3.layout.hierarchy(), - size = [1, 1]; // width, height - - function position(node, x, dx, dy) { - var children = node.children; - node.x = x; - node.y = node.depth * dy; - node.dx = dx; - node.dy = dy; - if (children && (n = children.length)) { - var i = -1, - n, - c, - d; - dx = node.value ? dx / node.value : 0; - while (++i < n) { - position(c = children[i], x, d = c.value * dx, dy); - x += d; - } - } - } - - function depth(node) { - var children = node.children, - d = 0; - if (children && (n = children.length)) { - var i = -1, - n; - while (++i < n) d = Math.max(d, depth(children[i])); - } - return 1 + d; - } - - function partition(d, i) { - var nodes = hierarchy.call(this, d, i); - position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); - return nodes; - } - - partition.size = function(x) { - if (!arguments.length) return size; - size = x; - return partition; - }; - - return d3_layout_hierarchyRebind(partition, hierarchy); -}; diff --git a/src/layout/pie.js b/src/layout/pie.js deleted file mode 100644 index 348c01ebcd853a..00000000000000 --- a/src/layout/pie.js +++ /dev/null @@ -1,99 +0,0 @@ -import "../arrays/range"; -import "../arrays/sum"; -import "../math/trigonometry"; -import "layout"; - -d3.layout.pie = function() { - var value = Number, - sort = d3_layout_pieSortByValue, - startAngle = 0, - endAngle = 2 * π; - - function pie(data) { - - // Compute the numeric values for each data element. - var values = data.map(function(d, i) { return +value.call(pie, d, i); }); - - // Compute the start angle. - var a = +(typeof startAngle === "function" - ? startAngle.apply(this, arguments) - : startAngle); - - // Compute the angular scale factor: from value to radians. - var k = ((typeof endAngle === "function" - ? endAngle.apply(this, arguments) - : endAngle) - a) - / d3.sum(values); - - // Optionally sort the data. - var index = d3.range(data.length); - if (sort != null) index.sort(sort === d3_layout_pieSortByValue - ? function(i, j) { return values[j] - values[i]; } - : function(i, j) { return sort(data[i], data[j]); }); - - // Compute the arcs! - // They are stored in the original data's order. - var arcs = []; - index.forEach(function(i) { - var d; - arcs[i] = { - data: data[i], - value: d = values[i], - startAngle: a, - endAngle: a += d * k - }; - }); - return arcs; - } - - /** - * Specifies the value function *x*, which returns a nonnegative numeric value - * for each datum. The default value function is `Number`. The value function - * is passed two arguments: the current datum and the current index. - */ - pie.value = function(x) { - if (!arguments.length) return value; - value = x; - return pie; - }; - - /** - * Specifies a sort comparison operator *x*. The comparator is passed two data - * elements from the data array, a and b; it returns a negative value if a is - * less than b, a positive value if a is greater than b, and zero if a equals - * b. - */ - pie.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return pie; - }; - - /** - * Specifies the overall start angle of the pie chart. Defaults to 0. The - * start angle can be specified either as a constant or as a function; in the - * case of a function, it is evaluated once per array (as opposed to per - * element). - */ - pie.startAngle = function(x) { - if (!arguments.length) return startAngle; - startAngle = x; - return pie; - }; - - /** - * Specifies the overall end angle of the pie chart. Defaults to 2π. The - * end angle can be specified either as a constant or as a function; in the - * case of a function, it is evaluated once per array (as opposed to per - * element). - */ - pie.endAngle = function(x) { - if (!arguments.length) return endAngle; - endAngle = x; - return pie; - }; - - return pie; -}; - -var d3_layout_pieSortByValue = {}; diff --git a/src/layout/stack.js b/src/layout/stack.js deleted file mode 100644 index 14a4cc6e03bee4..00000000000000 --- a/src/layout/stack.js +++ /dev/null @@ -1,245 +0,0 @@ -import "../arrays/map"; -import "../arrays/permute"; -import "../arrays/range"; -import "layout"; - -// data is two-dimensional array of x,y; we populate y0 -d3.layout.stack = function() { - var values = d3_identity, - order = d3_layout_stackOrderDefault, - offset = d3_layout_stackOffsetZero, - out = d3_layout_stackOut, - x = d3_layout_stackX, - y = d3_layout_stackY; - - function stack(data, index) { - - // Convert series to canonical two-dimensional representation. - var series = data.map(function(d, i) { - return values.call(stack, d, i); - }); - - // Convert each series to canonical [[x,y]] representation. - var points = series.map(function(d) { - return d.map(function(v, i) { - return [x.call(stack, v, i), y.call(stack, v, i)]; - }); - }); - - // Compute the order of series, and permute them. - var orders = order.call(stack, points, index); - series = d3.permute(series, orders); - points = d3.permute(points, orders); - - // Compute the baseline… - var offsets = offset.call(stack, points, index); - - // And propagate it to other series. - var n = series.length, - m = series[0].length, - i, - j, - o; - for (j = 0; j < m; ++j) { - out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); - for (i = 1; i < n; ++i) { - out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); - } - } - - return data; - } - - stack.values = function(x) { - if (!arguments.length) return values; - values = x; - return stack; - }; - - stack.order = function(x) { - if (!arguments.length) return order; - order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; - return stack; - }; - - stack.offset = function(x) { - if (!arguments.length) return offset; - offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; - return stack; - }; - - stack.x = function(z) { - if (!arguments.length) return x; - x = z; - return stack; - }; - - stack.y = function(z) { - if (!arguments.length) return y; - y = z; - return stack; - }; - - stack.out = function(z) { - if (!arguments.length) return out; - out = z; - return stack; - }; - - return stack; -}; - -function d3_layout_stackX(d) { - return d.x; -} - -function d3_layout_stackY(d) { - return d.y; -} - -function d3_layout_stackOut(d, y0, y) { - d.y0 = y0; - d.y = y; -} - -var d3_layout_stackOrders = d3.map({ - - "inside-out": function(data) { - var n = data.length, - i, - j, - max = data.map(d3_layout_stackMaxIndex), - sums = data.map(d3_layout_stackReduceSum), - index = d3.range(n).sort(function(a, b) { return max[a] - max[b]; }), - top = 0, - bottom = 0, - tops = [], - bottoms = []; - for (i = 0; i < n; ++i) { - j = index[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } - } - return bottoms.reverse().concat(tops); - }, - - "reverse": function(data) { - return d3.range(data.length).reverse(); - }, - - "default": d3_layout_stackOrderDefault - -}); - -var d3_layout_stackOffsets = d3.map({ - - "silhouette": function(data) { - var n = data.length, - m = data[0].length, - sums = [], - max = 0, - i, - j, - o, - y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o > max) max = o; - sums.push(o); - } - for (j = 0; j < m; ++j) { - y0[j] = (max - sums[j]) / 2; - } - return y0; - }, - - "wiggle": function(data) { - var n = data.length, - x = data[0], - m = x.length, - i, - j, - k, - s1, - s2, - s3, - dx, - o, - o0, - y0 = []; - y0[0] = o = o0 = 0; - for (j = 1; j < m; ++j) { - for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; - for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { - for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { - s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; - } - s2 += s3 * data[i][j][1]; - } - y0[j] = o -= s1 ? s2 / s1 * dx : 0; - if (o < o0) o0 = o; - } - for (j = 0; j < m; ++j) y0[j] -= o0; - return y0; - }, - - "expand": function(data) { - var n = data.length, - m = data[0].length, - k = 1 / n, - i, - j, - o, - y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; - else for (i = 0; i < n; i++) data[i][j][1] = k; - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }, - - "zero": d3_layout_stackOffsetZero - -}); - -function d3_layout_stackOrderDefault(data) { - return d3.range(data.length); -} - -function d3_layout_stackOffsetZero(data) { - var j = -1, - m = data[0].length, - y0 = []; - while (++j < m) y0[j] = 0; - return y0; -} - -function d3_layout_stackMaxIndex(array) { - var i = 1, - j = 0, - v = array[0][1], - k, - n = array.length; - for (; i < n; ++i) { - if ((k = array[i][1]) > v) { - j = i; - v = k; - } - } - return j; -} - -function d3_layout_stackReduceSum(d) { - return d.reduce(d3_layout_stackSum, 0); -} - -function d3_layout_stackSum(p, d) { - return p + d[1]; -} diff --git a/src/layout/tree.js b/src/layout/tree.js deleted file mode 100644 index d32a794939fdfd..00000000000000 --- a/src/layout/tree.js +++ /dev/null @@ -1,251 +0,0 @@ -import "layout"; -import "hierarchy"; - -// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm -d3.layout.tree = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), - separation = d3_layout_treeSeparation, - size = [1, 1], // width, height - nodeSize = false; - - function tree(d, i) { - var nodes = hierarchy.call(this, d, i), - root = nodes[0]; - - function firstWalk(node, previousSibling) { - var children = node.children, - layout = node._tree; - if (children && (n = children.length)) { - var n, - firstChild = children[0], - previousChild, - ancestor = firstChild, - child, - i = -1; - while (++i < n) { - child = children[i]; - firstWalk(child, previousChild); - ancestor = apportion(child, previousChild, ancestor); - previousChild = child; - } - d3_layout_treeShift(node); - var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - layout.mod = layout.prelim - midpoint; - } else { - layout.prelim = midpoint; - } - } else { - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - } - } - } - - function secondWalk(node, x) { - node.x = node._tree.prelim + x; - var children = node.children; - if (children && (n = children.length)) { - var i = -1, - n; - x += node._tree.mod; - while (++i < n) { - secondWalk(children[i], x); - } - } - } - - function apportion(node, previousSibling, ancestor) { - if (previousSibling) { - var vip = node, - vop = node, - vim = previousSibling, - vom = node.parent.children[0], - sip = vip._tree.mod, - sop = vop._tree.mod, - sim = vim._tree.mod, - som = vom._tree.mod, - shift; - while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { - vom = d3_layout_treeLeft(vom); - vop = d3_layout_treeRight(vop); - vop._tree.ancestor = node; - shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); - if (shift > 0) { - d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); - sip += shift; - sop += shift; - } - sim += vim._tree.mod; - sip += vip._tree.mod; - som += vom._tree.mod; - sop += vop._tree.mod; - } - if (vim && !d3_layout_treeRight(vop)) { - vop._tree.thread = vim; - vop._tree.mod += sim - sop; - } - if (vip && !d3_layout_treeLeft(vom)) { - vom._tree.thread = vip; - vom._tree.mod += sip - som; - ancestor = node; - } - } - return ancestor; - } - - // Initialize temporary layout variables. - d3_layout_treeVisitAfter(root, function(node, previousSibling) { - node._tree = { - ancestor: node, - prelim: 0, - mod: 0, - change: 0, - shift: 0, - number: previousSibling ? previousSibling._tree.number + 1 : 0 - }; - }); - - // Compute the layout using Buchheim et al.'s algorithm. - firstWalk(root); - secondWalk(root, -root._tree.prelim); - - // Compute the left-most, right-most, and depth-most nodes for extents. - var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), - right = d3_layout_treeSearch(root, d3_layout_treeRightmost), - deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), - x0 = left.x - separation(left, right) / 2, - x1 = right.x + separation(right, left) / 2, - y1 = deep.depth || 1; - - // Clear temporary layout variables; transform x and y. - d3_layout_treeVisitAfter(root, nodeSize ? function(node) { - node.x *= size[0]; - node.y = node.depth * size[1]; - delete node._tree; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = node.depth / y1 * size[1]; - delete node._tree; - }); - - return nodes; - } - - tree.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return tree; - }; - - tree.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return tree; - }; - - tree.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return tree; - }; - - return d3_layout_hierarchyRebind(tree, hierarchy); -}; - -function d3_layout_treeSeparation(a, b) { - return a.parent == b.parent ? 1 : 2; -} - -// function d3_layout_treeSeparationRadial(a, b) { -// return (a.parent == b.parent ? 1 : 2) / a.depth; -// } - -function d3_layout_treeLeft(node) { - var children = node.children; - return children && children.length ? children[0] : node._tree.thread; -} - -function d3_layout_treeRight(node) { - var children = node.children, - n; - return children && (n = children.length) ? children[n - 1] : node._tree.thread; -} - -function d3_layout_treeSearch(node, compare) { - var children = node.children; - if (children && (n = children.length)) { - var child, - n, - i = -1; - while (++i < n) { - if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { - node = child; - } - } - } - return node; -} - -function d3_layout_treeRightmost(a, b) { - return a.x - b.x; -} - -function d3_layout_treeLeftmost(a, b) { - return b.x - a.x; -} - -function d3_layout_treeDeepest(a, b) { - return a.depth - b.depth; -} - -function d3_layout_treeVisitAfter(node, callback) { - function visit(node, previousSibling) { - var children = node.children; - if (children && (n = children.length)) { - var child, - previousChild = null, - i = -1, - n; - while (++i < n) { - child = children[i]; - visit(child, previousChild); - previousChild = child; - } - } - callback(node, previousSibling); - } - visit(node, null); -} - -function d3_layout_treeShift(node) { - var shift = 0, - change = 0, - children = node.children, - i = children.length, - child; - while (--i >= 0) { - child = children[i]._tree; - child.prelim += shift; - child.mod += shift; - shift += child.shift + (change += child.change); - } -} - -function d3_layout_treeMove(ancestor, node, shift) { - ancestor = ancestor._tree; - node = node._tree; - var change = shift / (node.number - ancestor.number); - ancestor.change += change; - node.change -= change; - node.shift += shift; - node.prelim += shift; - node.mod += shift; -} - -function d3_layout_treeAncestor(vim, node, ancestor) { - return vim._tree.ancestor.parent == node.parent - ? vim._tree.ancestor - : ancestor; -} diff --git a/src/layout/treemap.js b/src/layout/treemap.js deleted file mode 100644 index 1a1d94afe48c93..00000000000000 --- a/src/layout/treemap.js +++ /dev/null @@ -1,230 +0,0 @@ -import "layout"; -import "hierarchy"; - -// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk -// Modified to support a target aspect ratio by Jeff Heer -d3.layout.treemap = function() { - var hierarchy = d3.layout.hierarchy(), - round = Math.round, - size = [1, 1], // width, height - padding = null, - pad = d3_layout_treemapPadNull, - sticky = false, - stickies, - mode = "squarify", - ratio = 0.5 * (1 + Math.sqrt(5)); // golden ratio - - // Compute the area for each child based on value & scale. - function scale(children, k) { - var i = -1, - n = children.length, - child, - area; - while (++i < n) { - area = (child = children[i]).value * (k < 0 ? 0 : k); - child.area = isNaN(area) || area <= 0 ? 0 : area; - } - } - - // Recursively arranges the specified node's children into squarified rows. - function squarify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), - row = [], - remaining = children.slice(), // copy-on-write - child, - best = Infinity, // the best row score so far - score, // the current row score - u = mode === "slice" ? rect.dx - : mode === "dice" ? rect.dy - : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx - : Math.min(rect.dx, rect.dy), // initial orientation - n; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while ((n = remaining.length) > 0) { - row.push(child = remaining[n - 1]); - row.area += child.area; - if (mode !== "squarify" || (score = worst(row, u)) <= best) { // continue with this orientation - remaining.pop(); - best = score; - } else { // abort, and try a different orientation - row.area -= row.pop().area; - position(row, u, rect, false); - u = Math.min(rect.dx, rect.dy); - row.length = row.area = 0; - best = Infinity; - } - } - if (row.length) { - position(row, u, rect, true); - row.length = row.area = 0; - } - children.forEach(squarify); - } - } - - // Recursively resizes the specified node's children into existing rows. - // Preserves the existing layout! - function stickify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), - remaining = children.slice(), // copy-on-write - child, - row = []; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while (child = remaining.pop()) { - row.push(child); - row.area += child.area; - if (child.z != null) { - position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); - row.length = row.area = 0; - } - } - children.forEach(stickify); - } - } - - // Computes the score for the specified row, as the worst aspect ratio. - function worst(row, u) { - var s = row.area, - r, - rmax = 0, - rmin = Infinity, - i = -1, - n = row.length; - while (++i < n) { - if (!(r = row[i].area)) continue; - if (r < rmin) rmin = r; - if (r > rmax) rmax = r; - } - s *= s; - u *= u; - return s - ? Math.max((u * rmax * ratio) / s, s / (u * rmin * ratio)) - : Infinity; - } - - // Positions the specified row of nodes. Modifies `rect`. - function position(row, u, rect, flush) { - var i = -1, - n = row.length, - x = rect.x, - y = rect.y, - v = u ? round(row.area / u) : 0, - o; - if (u == rect.dx) { // horizontal subdivision - if (flush || v > rect.dy) v = rect.dy; // over+underflow - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dy = v; - x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); - } - o.z = true; - o.dx += rect.x + rect.dx - x; // rounding error - rect.y += v; - rect.dy -= v; - } else { // vertical subdivision - if (flush || v > rect.dx) v = rect.dx; // over+underflow - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dx = v; - y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); - } - o.z = false; - o.dy += rect.y + rect.dy - y; // rounding error - rect.x += v; - rect.dx -= v; - } - } - - function treemap(d) { - var nodes = stickies || hierarchy(d), - root = nodes[0]; - root.x = 0; - root.y = 0; - root.dx = size[0]; - root.dy = size[1]; - if (stickies) hierarchy.revalue(root); - scale([root], root.dx * root.dy / root.value); - (stickies ? stickify : squarify)(root); - if (sticky) stickies = nodes; - return nodes; - } - - treemap.size = function(x) { - if (!arguments.length) return size; - size = x; - return treemap; - }; - - treemap.padding = function(x) { - if (!arguments.length) return padding; - - function padFunction(node) { - var p = x.call(treemap, node, node.depth); - return p == null - ? d3_layout_treemapPadNull(node) - : d3_layout_treemapPad(node, typeof p === "number" ? [p, p, p, p] : p); - } - - function padConstant(node) { - return d3_layout_treemapPad(node, x); - } - - var type; - pad = (padding = x) == null ? d3_layout_treemapPadNull - : (type = typeof x) === "function" ? padFunction - : type === "number" ? (x = [x, x, x, x], padConstant) - : padConstant; - return treemap; - }; - - treemap.round = function(x) { - if (!arguments.length) return round != Number; - round = x ? Math.round : Number; - return treemap; - }; - - treemap.sticky = function(x) { - if (!arguments.length) return sticky; - sticky = x; - stickies = null; - return treemap; - }; - - treemap.ratio = function(x) { - if (!arguments.length) return ratio; - ratio = x; - return treemap; - }; - - treemap.mode = function(x) { - if (!arguments.length) return mode; - mode = x + ""; - return treemap; - }; - - return d3_layout_hierarchyRebind(treemap, hierarchy); -}; - -function d3_layout_treemapPadNull(node) { - return {x: node.x, y: node.y, dx: node.dx, dy: node.dy}; -} - -function d3_layout_treemapPad(node, padding) { - var x = node.x + padding[3], - y = node.y + padding[0], - dx = node.dx - padding[1] - padding[3], - dy = node.dy - padding[0] - padding[2]; - if (dx < 0) { x += dx / 2; dx = 0; } - if (dy < 0) { y += dy / 2; dy = 0; } - return {x: x, y: y, dx: dx, dy: dy}; -} diff --git a/src/math/adder.js b/src/math/adder.js deleted file mode 100644 index 08fa289aeac64e..00000000000000 --- a/src/math/adder.js +++ /dev/null @@ -1,34 +0,0 @@ -// Adds floating point numbers with twice the normal precision. -// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and -// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3) -// 305–363 (1997). -// Code adapted from GeographicLib by Charles F. F. Karney, -// http://geographiclib.sourceforge.net/ -// See lib/geographiclib/LICENSE for details. - -function d3_adder() {} - -d3_adder.prototype = { - s: 0, // rounded value - t: 0, // exact error - add: function(y) { - d3_adderSum(y, this.t, d3_adderTemp); - d3_adderSum(d3_adderTemp.s, this.s, this); - if (this.s) this.t += d3_adderTemp.t; - else this.s = d3_adderTemp.t; - }, - reset: function() { - this.s = this.t = 0; - }, - valueOf: function() { - return this.s; - } -}; - -var d3_adderTemp = new d3_adder; - -function d3_adderSum(a, b, o) { - var x = o.s = a + b, // a + b - bv = x - a, av = x - bv; // b_virtual & a_virtual - o.t = (a - av) + (b - bv); // a_roundoff + b_roundoff -} diff --git a/src/math/index.js b/src/math/index.js deleted file mode 100644 index 20f6966e2955e2..00000000000000 --- a/src/math/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import "random"; -import "transform"; diff --git a/src/math/number.js b/src/math/number.js deleted file mode 100644 index ed03c6ff586002..00000000000000 --- a/src/math/number.js +++ /dev/null @@ -1,3 +0,0 @@ -function d3_number(x) { - return x != null && !isNaN(x); -} diff --git a/src/math/random.js b/src/math/random.js deleted file mode 100644 index 151f7b1cb5adfe..00000000000000 --- a/src/math/random.js +++ /dev/null @@ -1,28 +0,0 @@ -d3.random = { - normal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - return function() { - var x, y, r; - do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); - return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); - }; - }, - logNormal: function() { - var random = d3.random.normal.apply(d3, arguments); - return function() { - return Math.exp(random()); - }; - }, - irwinHall: function(m) { - return function() { - for (var s = 0, j = 0; j < m; j++) s += Math.random(); - return s / m; - }; - } -}; diff --git a/src/math/transform.js b/src/math/transform.js deleted file mode 100644 index 8a5e6cde5780d9..00000000000000 --- a/src/math/transform.js +++ /dev/null @@ -1,64 +0,0 @@ -import "../core/document"; -import "../core/ns"; - -d3.transform = function(string) { - var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); - return (d3.transform = function(string) { - if (string != null) { - g.setAttribute("transform", string); - var t = g.transform.baseVal.consolidate(); - } - return new d3_transform(t ? t.matrix : d3_transformIdentity); - })(string); -}; - -// Compute x-scale and normalize the first row. -// Compute shear and make second row orthogonal to first. -// Compute y-scale and normalize the second row. -// Finally, compute the rotation. -function d3_transform(m) { - var r0 = [m.a, m.b], - r1 = [m.c, m.d], - kx = d3_transformNormalize(r0), - kz = d3_transformDot(r0, r1), - ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; - if (r0[0] * r1[1] < r1[0] * r0[1]) { - r0[0] *= -1; - r0[1] *= -1; - kx *= -1; - kz *= -1; - } - this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; - this.translate = [m.e, m.f]; - this.scale = [kx, ky]; - this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; -}; - -d3_transform.prototype.toString = function() { - return "translate(" + this.translate - + ")rotate(" + this.rotate - + ")skewX(" + this.skew - + ")scale(" + this.scale - + ")"; -}; - -function d3_transformDot(a, b) { - return a[0] * b[0] + a[1] * b[1]; -} - -function d3_transformNormalize(a) { - var k = Math.sqrt(d3_transformDot(a, a)); - if (k) { - a[0] /= k; - a[1] /= k; - } - return k; -} - -function d3_transformCombine(a, b, k) { - a[0] += k * b[0]; - a[1] += k * b[1]; - return a; -} - -var d3_transformIdentity = {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}; diff --git a/src/math/trigonometry.js b/src/math/trigonometry.js deleted file mode 100644 index 2477e028c91bee..00000000000000 --- a/src/math/trigonometry.js +++ /dev/null @@ -1,33 +0,0 @@ -var π = Math.PI, - ε = 1e-6, - ε2 = ε * ε, - d3_radians = π / 180, - d3_degrees = 180 / π; - -function d3_sgn(x) { - return x > 0 ? 1 : x < 0 ? -1 : 0; -} - -function d3_acos(x) { - return x > 1 ? 0 : x < -1 ? π : Math.acos(x); -} - -function d3_asin(x) { - return x > 1 ? π / 2 : x < -1 ? -π / 2 : Math.asin(x); -} - -function d3_sinh(x) { - return (Math.exp(x) - Math.exp(-x)) / 2; -} - -function d3_cosh(x) { - return (Math.exp(x) + Math.exp(-x)) / 2; -} - -function d3_tanh(x) { - return d3_sinh(x) / d3_cosh(x); -} - -function d3_haversin(x) { - return (x = Math.sin(x / 2)) * x; -} diff --git a/src/scale/bilinear.js b/src/scale/bilinear.js deleted file mode 100644 index ff014777c654e5..00000000000000 --- a/src/scale/bilinear.js +++ /dev/null @@ -1,7 +0,0 @@ -function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { - var u = uninterpolate(domain[0], domain[1]), - i = interpolate(range[0], range[1]); - return function(x) { - return i(u(x)); - }; -} diff --git a/src/scale/category.js b/src/scale/category.js deleted file mode 100644 index 3324917c6fc509..00000000000000 --- a/src/scale/category.js +++ /dev/null @@ -1,58 +0,0 @@ -import "../color/rgb"; -import "ordinal"; -import "scale"; - -/* - * This product includes color specifications and designs developed by Cynthia - * Brewer (http://colorbrewer.org/). See lib/colorbrewer for more information. - */ - -d3.scale.category10 = function() { - return d3.scale.ordinal().range(d3_category10); -}; - -d3.scale.category20 = function() { - return d3.scale.ordinal().range(d3_category20); -}; - -d3.scale.category20b = function() { - return d3.scale.ordinal().range(d3_category20b); -}; - -d3.scale.category20c = function() { - return d3.scale.ordinal().range(d3_category20c); -}; - -var d3_category10 = [ - 0x1f77b4, 0xff7f0e, 0x2ca02c, 0xd62728, 0x9467bd, - 0x8c564b, 0xe377c2, 0x7f7f7f, 0xbcbd22, 0x17becf -].map(d3_rgbString); - -var d3_category20 = [ - 0x1f77b4, 0xaec7e8, - 0xff7f0e, 0xffbb78, - 0x2ca02c, 0x98df8a, - 0xd62728, 0xff9896, - 0x9467bd, 0xc5b0d5, - 0x8c564b, 0xc49c94, - 0xe377c2, 0xf7b6d2, - 0x7f7f7f, 0xc7c7c7, - 0xbcbd22, 0xdbdb8d, - 0x17becf, 0x9edae5 -].map(d3_rgbString); - -var d3_category20b = [ - 0x393b79, 0x5254a3, 0x6b6ecf, 0x9c9ede, - 0x637939, 0x8ca252, 0xb5cf6b, 0xcedb9c, - 0x8c6d31, 0xbd9e39, 0xe7ba52, 0xe7cb94, - 0x843c39, 0xad494a, 0xd6616b, 0xe7969c, - 0x7b4173, 0xa55194, 0xce6dbd, 0xde9ed6 -].map(d3_rgbString); - -var d3_category20c = [ - 0x3182bd, 0x6baed6, 0x9ecae1, 0xc6dbef, - 0xe6550d, 0xfd8d3c, 0xfdae6b, 0xfdd0a2, - 0x31a354, 0x74c476, 0xa1d99b, 0xc7e9c0, - 0x756bb1, 0x9e9ac8, 0xbcbddc, 0xdadaeb, - 0x636363, 0x969696, 0xbdbdbd, 0xd9d9d9 -].map(d3_rgbString); diff --git a/src/scale/identity.js b/src/scale/identity.js deleted file mode 100644 index 0cc78095953cac..00000000000000 --- a/src/scale/identity.js +++ /dev/null @@ -1,33 +0,0 @@ -import "linear"; -import "scale"; - -d3.scale.identity = function() { - return d3_scale_identity([0, 1]); -}; - -function d3_scale_identity(domain) { - - function identity(x) { return +x; } - - identity.invert = identity; - - identity.domain = identity.range = function(x) { - if (!arguments.length) return domain; - domain = x.map(identity); - return identity; - }; - - identity.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - - identity.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - - identity.copy = function() { - return d3_scale_identity(domain); - }; - - return identity; -} diff --git a/src/scale/index.js b/src/scale/index.js deleted file mode 100644 index 271ea8d7138916..00000000000000 --- a/src/scale/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import "scale"; -import "linear"; -import "log"; -import "pow"; -import "sqrt"; -import "ordinal"; -import "category"; -import "quantile"; -import "quantize"; -import "threshold"; -import "identity"; diff --git a/src/scale/linear.js b/src/scale/linear.js deleted file mode 100644 index 41bf81802fc3d8..00000000000000 --- a/src/scale/linear.js +++ /dev/null @@ -1,122 +0,0 @@ -import "../arrays/range"; -import "../core/rebind"; -import "../interpolate/interpolate"; -import "../interpolate/round"; -import "../interpolate/uninterpolate"; -import "../format/format"; -import "bilinear"; -import "nice"; -import "polylinear"; -import "scale"; - -d3.scale.linear = function() { - return d3_scale_linear([0, 1], [0, 1], d3_interpolate, false); -}; - -function d3_scale_linear(domain, range, interpolate, clamp) { - var output, - input; - - function rescale() { - var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, - uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; - output = linear(domain, range, uninterpolate, interpolate); - input = linear(range, domain, uninterpolate, d3_interpolate); - return scale; - } - - function scale(x) { - return output(x); - } - - // Note: requires range is coercible to number! - scale.invert = function(y) { - return input(y); - }; - - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(Number); - return rescale(); - }; - - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - - scale.rangeRound = function(x) { - return scale.range(x).interpolate(d3_interpolateRound); - }; - - scale.clamp = function(x) { - if (!arguments.length) return clamp; - clamp = x; - return rescale(); - }; - - scale.interpolate = function(x) { - if (!arguments.length) return interpolate; - interpolate = x; - return rescale(); - }; - - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - - scale.nice = function(m) { - d3_scale_linearNice(domain, m); - return rescale(); - }; - - scale.copy = function() { - return d3_scale_linear(domain, range, interpolate, clamp); - }; - - return rescale(); -} - -function d3_scale_linearRebind(scale, linear) { - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); -} - -function d3_scale_linearNice(domain, m) { - return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); -} - -function d3_scale_linearTickRange(domain, m) { - if (m == null) m = 10; - - var extent = d3_scaleExtent(domain), - span = extent[1] - extent[0], - step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), - err = m / span * step; - - // Filter ticks to get closer to the desired count. - if (err <= .15) step *= 10; - else if (err <= .35) step *= 5; - else if (err <= .75) step *= 2; - - // Round start and stop values to step interval. - extent[0] = Math.ceil(extent[0] / step) * step; - extent[1] = Math.floor(extent[1] / step) * step + step * .5; // inclusive - extent[2] = step; - return extent; -} - -function d3_scale_linearTicks(domain, m) { - return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); -} - -function d3_scale_linearTickFormat(domain, m, format) { - var precision = -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01); - return d3.format(format - ? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) { return [b, c, d, e, f, g, h, i || "." + (precision - (j === "%") * 2), j].join(""); }) - : ",." + precision + "f"); -} diff --git a/src/scale/log.js b/src/scale/log.js deleted file mode 100644 index 5234a5811b97cb..00000000000000 --- a/src/scale/log.js +++ /dev/null @@ -1,92 +0,0 @@ -import "../format/format"; -import "linear"; -import "nice"; -import "scale"; - -d3.scale.log = function() { - return d3_scale_log(d3.scale.linear().domain([0, 1]), 10, true, [1, 10]); -}; - -function d3_scale_log(linear, base, positive, domain) { - - function log(x) { - return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); - } - - function pow(x) { - return positive ? Math.pow(base, x) : -Math.pow(base, -x); - } - - function scale(x) { - return linear(log(x)); - } - - scale.invert = function(x) { - return pow(linear.invert(x)); - }; - - scale.domain = function(x) { - if (!arguments.length) return domain; - positive = x[0] >= 0; - linear.domain((domain = x.map(Number)).map(log)); - return scale; - }; - - scale.base = function(_) { - if (!arguments.length) return base; - base = +_; - linear.domain(domain.map(log)); - return scale; - }; - - scale.nice = function() { - var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); - linear.domain(niced); // do not modify the linear scale’s domain in-place! - domain = niced.map(pow); - return scale; - }; - - scale.ticks = function() { - var extent = d3_scaleExtent(domain), - ticks = [], - u = extent[0], - v = extent[1], - i = Math.floor(log(u)), - j = Math.ceil(log(v)), - n = base % 1 ? 2 : base; - if (isFinite(j - i)) { - if (positive) { - for (; i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); - ticks.push(pow(i)); - } else { - ticks.push(pow(i)); - for (; i++ < j;) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); - } - for (i = 0; ticks[i] < u; i++) {} // strip small values - for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values - ticks = ticks.slice(i, j); - } - return ticks; - }; - - scale.tickFormat = function(n, format) { - if (!arguments.length) return d3_scale_logFormat; - if (arguments.length < 2) format = d3_scale_logFormat; - else if (typeof format !== "function") format = d3.format(format); - var k = Math.max(.1, n / scale.ticks().length), - f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, Math.floor), - e; - return function(d) { - return d / pow(f(log(d) + e)) <= k ? format(d) : ""; - }; - }; - - scale.copy = function() { - return d3_scale_log(linear.copy(), base, positive, domain); - }; - - return d3_scale_linearRebind(scale, linear); -} - -var d3_scale_logFormat = d3.format(".0e"), - d3_scale_logNiceNegative = {floor: function(x) { return -Math.ceil(-x); }, ceil: function(x) { return -Math.floor(-x); }}; diff --git a/src/scale/nice.js b/src/scale/nice.js deleted file mode 100644 index f355ceb9b8e2c9..00000000000000 --- a/src/scale/nice.js +++ /dev/null @@ -1,28 +0,0 @@ -function d3_scale_nice(domain, nice) { - var i0 = 0, - i1 = domain.length - 1, - x0 = domain[i0], - x1 = domain[i1], - dx; - - if (x1 < x0) { - dx = i0, i0 = i1, i1 = dx; - dx = x0, x0 = x1, x1 = dx; - } - - domain[i0] = nice.floor(x0); - domain[i1] = nice.ceil(x1); - return domain; -} - -function d3_scale_niceStep(step) { - return step ? { - floor: function(x) { return Math.floor(x / step) * step; }, - ceil: function(x) { return Math.ceil(x / step) * step; } - } : d3_scale_niceIdentity; -} - -var d3_scale_niceIdentity = { - floor: d3_identity, - ceil: d3_identity -}; diff --git a/src/scale/ordinal.js b/src/scale/ordinal.js deleted file mode 100644 index 02ffee93756b05..00000000000000 --- a/src/scale/ordinal.js +++ /dev/null @@ -1,92 +0,0 @@ -import "../arrays/map"; -import "../arrays/range"; -import "scale"; - -d3.scale.ordinal = function() { - return d3_scale_ordinal([], {t: "range", a: [[]]}); -}; - -function d3_scale_ordinal(domain, ranger) { - var index, - range, - rangeBand; - - function scale(x) { - return range[((index.get(x) || ranger.t === "range" && index.set(x, domain.push(x))) - 1) % range.length]; - } - - function steps(start, step) { - return d3.range(domain.length).map(function(i) { return start + step * i; }); - } - - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = []; - index = new d3_Map; - var i = -1, n = x.length, xi; - while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); - return scale[ranger.t].apply(scale, ranger.a); - }; - - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - rangeBand = 0; - ranger = {t: "range", a: arguments}; - return scale; - }; - - scale.rangePoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], - stop = x[1], - step = (stop - start) / (Math.max(1, domain.length - 1) + padding); - range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); - rangeBand = 0; - ranger = {t: "rangePoints", a: arguments}; - return scale; - }; - - scale.rangeBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], - start = x[reverse - 0], - stop = x[1 - reverse], - step = (stop - start) / (domain.length - padding + 2 * outerPadding); - range = steps(start + step * outerPadding, step); - if (reverse) range.reverse(); - rangeBand = step * (1 - padding); - ranger = {t: "rangeBands", a: arguments}; - return scale; - }; - - scale.rangeRoundBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], - start = x[reverse - 0], - stop = x[1 - reverse], - step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), - error = stop - start - (domain.length - padding) * step; - range = steps(start + Math.round(error / 2), step); - if (reverse) range.reverse(); - rangeBand = Math.round(step * (1 - padding)); - ranger = {t: "rangeRoundBands", a: arguments}; - return scale; - }; - - scale.rangeBand = function() { - return rangeBand; - }; - - scale.rangeExtent = function() { - return d3_scaleExtent(ranger.a[0]); - }; - - scale.copy = function() { - return d3_scale_ordinal(domain, ranger); - }; - - return scale.domain(domain); -} diff --git a/src/scale/polylinear.js b/src/scale/polylinear.js deleted file mode 100644 index 3d729d785dd57f..00000000000000 --- a/src/scale/polylinear.js +++ /dev/null @@ -1,24 +0,0 @@ -import "../arrays/bisect"; - -function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { - var u = [], - i = [], - j = 0, - k = Math.min(domain.length, range.length) - 1; - - // Handle descending domains. - if (domain[k] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - - while (++j <= k) { - u.push(uninterpolate(domain[j - 1], domain[j])); - i.push(interpolate(range[j - 1], range[j])); - } - - return function(x) { - var j = d3.bisect(domain, x, 1, k) - 1; - return i[j](u[j](x)); - }; -} diff --git a/src/scale/pow.js b/src/scale/pow.js deleted file mode 100644 index 9a249e31cb80f7..00000000000000 --- a/src/scale/pow.js +++ /dev/null @@ -1,58 +0,0 @@ -import "linear"; -import "nice"; -import "scale"; - -d3.scale.pow = function() { - return d3_scale_pow(d3.scale.linear(), 1, [0, 1]); -}; - -function d3_scale_pow(linear, exponent, domain) { - var powp = d3_scale_powPow(exponent), - powb = d3_scale_powPow(1 / exponent); - - function scale(x) { - return linear(powp(x)); - } - - scale.invert = function(x) { - return powb(linear.invert(x)); - }; - - scale.domain = function(x) { - if (!arguments.length) return domain; - linear.domain((domain = x.map(Number)).map(powp)); - return scale; - }; - - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - - scale.nice = function(m) { - return scale.domain(d3_scale_linearNice(domain, m)); - }; - - scale.exponent = function(x) { - if (!arguments.length) return exponent; - powp = d3_scale_powPow(exponent = x); - powb = d3_scale_powPow(1 / exponent); - linear.domain(domain.map(powp)); - return scale; - }; - - scale.copy = function() { - return d3_scale_pow(linear.copy(), exponent, domain); - }; - - return d3_scale_linearRebind(scale, linear); -} - -function d3_scale_powPow(e) { - return function(x) { - return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); - }; -} diff --git a/src/scale/quantile.js b/src/scale/quantile.js deleted file mode 100644 index 2e9d84d10b26f6..00000000000000 --- a/src/scale/quantile.js +++ /dev/null @@ -1,54 +0,0 @@ -import "../arrays/ascending"; -import "../arrays/bisect"; -import "../arrays/quantile"; -import "scale"; - -d3.scale.quantile = function() { - return d3_scale_quantile([], []); -}; - -function d3_scale_quantile(domain, range) { - var thresholds; - - function rescale() { - var k = 0, - q = range.length; - thresholds = []; - while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); - return scale; - } - - function scale(x) { - if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; - } - - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.filter(function(d) { return !isNaN(d); }).sort(d3.ascending); - return rescale(); - }; - - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - - scale.quantiles = function() { - return thresholds; - }; - - scale.invertExtent = function(y) { - y = range.indexOf(y); - return y < 0 ? [NaN, NaN] : [ - y > 0 ? thresholds[y - 1] : domain[0], - y < thresholds.length ? thresholds[y] : domain[domain.length - 1] - ]; - }; - - scale.copy = function() { - return d3_scale_quantile(domain, range); // copy on write! - }; - - return rescale(); -} diff --git a/src/scale/quantize.js b/src/scale/quantize.js deleted file mode 100644 index f3b656d93ee989..00000000000000 --- a/src/scale/quantize.js +++ /dev/null @@ -1,44 +0,0 @@ -import "scale"; - -d3.scale.quantize = function() { - return d3_scale_quantize(0, 1, [0, 1]); -}; - -function d3_scale_quantize(x0, x1, range) { - var kx, i; - - function scale(x) { - return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; - } - - function rescale() { - kx = range.length / (x1 - x0); - i = range.length - 1; - return scale; - } - - scale.domain = function(x) { - if (!arguments.length) return [x0, x1]; - x0 = +x[0]; - x1 = +x[x.length - 1]; - return rescale(); - }; - - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - - scale.invertExtent = function(y) { - y = range.indexOf(y); - y = y < 0 ? NaN : y / kx + x0; - return [y, y + 1 / kx]; - }; - - scale.copy = function() { - return d3_scale_quantize(x0, x1, range); // copy on write - }; - - return rescale(); -} diff --git a/src/scale/scale.js b/src/scale/scale.js deleted file mode 100644 index b7952d4402a137..00000000000000 --- a/src/scale/scale.js +++ /dev/null @@ -1,10 +0,0 @@ -d3.scale = {}; - -function d3_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [start, stop] : [stop, start]; -} - -function d3_scaleRange(scale) { - return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); -} diff --git a/src/scale/sqrt.js b/src/scale/sqrt.js deleted file mode 100644 index a05c287494b270..00000000000000 --- a/src/scale/sqrt.js +++ /dev/null @@ -1,6 +0,0 @@ -import "pow"; -import "scale"; - -d3.scale.sqrt = function() { - return d3.scale.pow().exponent(.5); -}; diff --git a/src/scale/threshold.js b/src/scale/threshold.js deleted file mode 100644 index 41b04c2c163fea..00000000000000 --- a/src/scale/threshold.js +++ /dev/null @@ -1,36 +0,0 @@ -import "../arrays/bisect"; -import "scale"; - -d3.scale.threshold = function() { - return d3_scale_threshold([.5], [0, 1]); -}; - -function d3_scale_threshold(domain, range) { - - function scale(x) { - if (x <= x) return range[d3.bisect(domain, x)]; - } - - scale.domain = function(_) { - if (!arguments.length) return domain; - domain = _; - return scale; - }; - - scale.range = function(_) { - if (!arguments.length) return range; - range = _; - return scale; - }; - - scale.invertExtent = function(y) { - y = range.indexOf(y); - return [domain[y - 1], domain[y]]; - }; - - scale.copy = function() { - return d3_scale_threshold(domain, range); - }; - - return scale; -}; diff --git a/src/selection/append.js b/src/selection/append.js deleted file mode 100644 index 7c8afa9fd0b6f8..00000000000000 --- a/src/selection/append.js +++ /dev/null @@ -1,16 +0,0 @@ -import "../core/document"; -import "../core/ns"; -import "selection"; - -d3_selectionPrototype.append = function(name) { - name = d3_selection_creator(name); - return this.select(function() { - return this.appendChild(name.apply(this, arguments)); - }); -}; - -function d3_selection_creator(name) { - return typeof name === "function" ? name - : (name = d3.ns.qualify(name)).local ? function() { return d3_document.createElementNS(name.space, name.local); } - : function() { return d3_document.createElementNS(this.namespaceURI, name); }; -} diff --git a/src/selection/attr.js b/src/selection/attr.js deleted file mode 100644 index 723199a4c89788..00000000000000 --- a/src/selection/attr.js +++ /dev/null @@ -1,62 +0,0 @@ -import "../core/ns"; -import "selection"; - -d3_selectionPrototype.attr = function(name, value) { - if (arguments.length < 2) { - - // For attr(string), return the attribute value for the first node. - if (typeof name === "string") { - var node = this.node(); - name = d3.ns.qualify(name); - return name.local - ? node.getAttributeNS(name.space, name.local) - : node.getAttribute(name); - } - - // For attr(object), the object specifies the names and values of the - // attributes to set or remove. The values may be functions that are - // evaluated for each element. - for (value in name) this.each(d3_selection_attr(value, name[value])); - return this; - } - - return this.each(d3_selection_attr(name, value)); -}; - -function d3_selection_attr(name, value) { - name = d3.ns.qualify(name); - - // For attr(string, null), remove the attribute with the specified name. - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - - // For attr(string, string), set the attribute with the specified name. - function attrConstant() { - this.setAttribute(name, value); - } - function attrConstantNS() { - this.setAttributeNS(name.space, name.local, value); - } - - // For attr(string, function), evaluate the function for each element, and set - // or remove the attribute as appropriate. - function attrFunction() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttribute(name); - else this.setAttribute(name, x); - } - function attrFunctionNS() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttributeNS(name.space, name.local); - else this.setAttributeNS(name.space, name.local, x); - } - - return value == null - ? (name.local ? attrNullNS : attrNull) : (typeof value === "function" - ? (name.local ? attrFunctionNS : attrFunction) - : (name.local ? attrConstantNS : attrConstant)); -} diff --git a/src/selection/call.js b/src/selection/call.js deleted file mode 100644 index 3dfc3865bec3b4..00000000000000 --- a/src/selection/call.js +++ /dev/null @@ -1,8 +0,0 @@ -import "../core/array"; -import "selection"; - -d3_selectionPrototype.call = function(callback) { - var args = d3_array(arguments); - callback.apply(args[0] = this, args); - return this; -}; diff --git a/src/selection/classed.js b/src/selection/classed.js deleted file mode 100644 index ed8f7ca5f2c7d7..00000000000000 --- a/src/selection/classed.js +++ /dev/null @@ -1,72 +0,0 @@ -import "../format/collapse"; -import "../format/requote"; -import "selection"; - -d3_selectionPrototype.classed = function(name, value) { - if (arguments.length < 2) { - - // For classed(string), return true only if the first node has the specified - // class or classes. Note that even if the browser supports DOMTokenList, it - // probably doesn't support it on SVG elements (which can be animated). - if (typeof name === "string") { - var node = this.node(), - n = (name = name.trim().split(/^|\s+/g)).length, - i = -1; - if (value = node.classList) { - while (++i < n) if (!value.contains(name[i])) return false; - } else { - value = node.getAttribute("class"); - while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; - } - return true; - } - - // For classed(object), the object specifies the names of classes to add or - // remove. The values may be functions that are evaluated for each element. - for (value in name) this.each(d3_selection_classed(value, name[value])); - return this; - } - - // Otherwise, both a name and a value are specified, and are handled as below. - return this.each(d3_selection_classed(name, value)); -}; - -function d3_selection_classedRe(name) { - return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); -} - -// Multiple class names are allowed (e.g., "foo bar"). -function d3_selection_classed(name, value) { - name = name.trim().split(/\s+/).map(d3_selection_classedName); - var n = name.length; - - function classedConstant() { - var i = -1; - while (++i < n) name[i](this, value); - } - - // When the value is a function, the function is still evaluated only once per - // element even if there are multiple class names. - function classedFunction() { - var i = -1, x = value.apply(this, arguments); - while (++i < n) name[i](this, x); - } - - return typeof value === "function" - ? classedFunction - : classedConstant; -} - -function d3_selection_classedName(name) { - var re = d3_selection_classedRe(name); - return function(node, value) { - if (c = node.classList) return value ? c.add(name) : c.remove(name); - var c = node.getAttribute("class") || ""; - if (value) { - re.lastIndex = 0; - if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); - } else { - node.setAttribute("class", d3_collapse(c.replace(re, " "))); - } - }; -} diff --git a/src/selection/data.js b/src/selection/data.js deleted file mode 100644 index 2173dcbdb9f75f..00000000000000 --- a/src/selection/data.js +++ /dev/null @@ -1,118 +0,0 @@ -import "../arrays/map"; -import "selection"; - -d3_selectionPrototype.data = function(value, key) { - var i = -1, - n = this.length, - group, - node; - - // If no value is specified, return the first value. - if (!arguments.length) { - value = new Array(n = (group = this[0]).length); - while (++i < n) { - if (node = group[i]) { - value[i] = node.__data__; - } - } - return value; - } - - function bind(group, groupData) { - var i, - n = group.length, - m = groupData.length, - n0 = Math.min(n, m), - updateNodes = new Array(m), - enterNodes = new Array(m), - exitNodes = new Array(n), - node, - nodeData; - - if (key) { - var nodeByKeyValue = new d3_Map, - dataByKeyValue = new d3_Map, - keyValues = [], - keyValue; - - for (i = -1; ++i < n;) { - keyValue = key.call(node = group[i], node.__data__, i); - if (nodeByKeyValue.has(keyValue)) { - exitNodes[i] = node; // duplicate selection key - } else { - nodeByKeyValue.set(keyValue, node); - } - keyValues.push(keyValue); - } - - for (i = -1; ++i < m;) { - keyValue = key.call(groupData, nodeData = groupData[i], i); - if (node = nodeByKeyValue.get(keyValue)) { - updateNodes[i] = node; - node.__data__ = nodeData; - } else if (!dataByKeyValue.has(keyValue)) { // no duplicate data key - enterNodes[i] = d3_selection_dataNode(nodeData); - } - dataByKeyValue.set(keyValue, nodeData); - nodeByKeyValue.remove(keyValue); - } - - for (i = -1; ++i < n;) { - if (nodeByKeyValue.has(keyValues[i])) { - exitNodes[i] = group[i]; - } - } - } else { - for (i = -1; ++i < n0;) { - node = group[i]; - nodeData = groupData[i]; - if (node) { - node.__data__ = nodeData; - updateNodes[i] = node; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - } - for (; i < m; ++i) { - enterNodes[i] = d3_selection_dataNode(groupData[i]); - } - for (; i < n; ++i) { - exitNodes[i] = group[i]; - } - } - - enterNodes.update - = updateNodes; - - enterNodes.parentNode - = updateNodes.parentNode - = exitNodes.parentNode - = group.parentNode; - - enter.push(enterNodes); - update.push(updateNodes); - exit.push(exitNodes); - } - - var enter = d3_selection_enter([]), - update = d3_selection([]), - exit = d3_selection([]); - - if (typeof value === "function") { - while (++i < n) { - bind(group = this[i], value.call(group, group.parentNode.__data__, i)); - } - } else { - while (++i < n) { - bind(group = this[i], value); - } - } - - update.enter = function() { return enter; }; - update.exit = function() { return exit; }; - return update; -}; - -function d3_selection_dataNode(data) { - return {__data__: data}; -} diff --git a/src/selection/datum.js b/src/selection/datum.js deleted file mode 100644 index 5434de48c8b93d..00000000000000 --- a/src/selection/datum.js +++ /dev/null @@ -1,7 +0,0 @@ -import "selection"; - -d3_selectionPrototype.datum = function(value) { - return arguments.length - ? this.property("__data__", value) - : this.property("__data__"); -}; diff --git a/src/selection/each.js b/src/selection/each.js deleted file mode 100644 index 45b8603c6b91f1..00000000000000 --- a/src/selection/each.js +++ /dev/null @@ -1,16 +0,0 @@ -import "selection"; - -d3_selectionPrototype.each = function(callback) { - return d3_selection_each(this, function(node, i, j) { - callback.call(node, node.__data__, i, j); - }); -}; - -function d3_selection_each(groups, callback) { - for (var j = 0, m = groups.length; j < m; j++) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { - if (node = group[i]) callback(node, i, j); - } - } - return groups; -} diff --git a/src/selection/empty.js b/src/selection/empty.js deleted file mode 100644 index 6135c23fb1dbde..00000000000000 --- a/src/selection/empty.js +++ /dev/null @@ -1,5 +0,0 @@ -import "selection"; - -d3_selectionPrototype.empty = function() { - return !this.node(); -}; diff --git a/src/selection/enter-insert.js b/src/selection/enter-insert.js deleted file mode 100644 index f7d6c15026edaf..00000000000000 --- a/src/selection/enter-insert.js +++ /dev/null @@ -1,20 +0,0 @@ -import "selection"; -import "enter"; - -d3_selection_enterPrototype.insert = function(name, before) { - if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); - return d3_selectionPrototype.insert.call(this, name, before); -}; - -function d3_selection_enterInsertBefore(enter) { - var i0, j0; - return function(d, i, j) { - var group = enter[j].update, - n = group.length, - node; - if (j != j0) j0 = j, i0 = 0; - if (i >= i0) i0 = i + 1; - while (!(node = group[i0]) && ++i0 < n); - return node; - }; -} diff --git a/src/selection/enter-select.js b/src/selection/enter-select.js deleted file mode 100644 index 2764c6ceef3d5b..00000000000000 --- a/src/selection/enter-select.js +++ /dev/null @@ -1,27 +0,0 @@ -import "selection"; -import "enter"; - -d3_selection_enterPrototype.select = function(selector) { - var subgroups = [], - subgroup, - subnode, - upgroup, - group, - node; - - for (var j = -1, m = this.length; ++j < m;) { - upgroup = (group = this[j]).update; - subgroups.push(subgroup = []); - subgroup.parentNode = group.parentNode; - for (var i = -1, n = group.length; ++i < n;) { - if (node = group[i]) { - subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); - subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - - return d3_selection(subgroups); -}; diff --git a/src/selection/enter.js b/src/selection/enter.js deleted file mode 100644 index 2533582efdfcde..00000000000000 --- a/src/selection/enter.js +++ /dev/null @@ -1,21 +0,0 @@ -import "../core/subclass"; -import "selection"; - -function d3_selection_enter(selection) { - d3_subclass(selection, d3_selection_enterPrototype); - return selection; -} - -var d3_selection_enterPrototype = []; - -d3.selection.enter = d3_selection_enter; -d3.selection.enter.prototype = d3_selection_enterPrototype; - -d3_selection_enterPrototype.append = d3_selectionPrototype.append; -d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; -d3_selection_enterPrototype.node = d3_selectionPrototype.node; -d3_selection_enterPrototype.call = d3_selectionPrototype.call; -d3_selection_enterPrototype.size = d3_selectionPrototype.size; - -import "enter-select"; -import "enter-insert"; diff --git a/src/selection/filter.js b/src/selection/filter.js deleted file mode 100644 index 27d9983522e32e..00000000000000 --- a/src/selection/filter.js +++ /dev/null @@ -1,28 +0,0 @@ -import "selection"; - -d3_selectionPrototype.filter = function(filter) { - var subgroups = [], - subgroup, - group, - node; - - if (typeof filter !== "function") filter = d3_selection_filter(filter); - - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i)) { - subgroup.push(node); - } - } - } - - return d3_selection(subgroups); -}; - -function d3_selection_filter(selector) { - return function() { - return d3_selectMatches(this, selector); - }; -} diff --git a/src/selection/html.js b/src/selection/html.js deleted file mode 100644 index 19f475d7abe08e..00000000000000 --- a/src/selection/html.js +++ /dev/null @@ -1,10 +0,0 @@ -import "selection"; - -d3_selectionPrototype.html = function(value) { - return arguments.length - ? this.each(typeof value === "function" - ? function() { var v = value.apply(this, arguments); this.innerHTML = v == null ? "" : v; } : value == null - ? function() { this.innerHTML = ""; } - : function() { this.innerHTML = value; }) - : this.node().innerHTML; -}; diff --git a/src/selection/index.js b/src/selection/index.js deleted file mode 100644 index 3350277372863d..00000000000000 --- a/src/selection/index.js +++ /dev/null @@ -1 +0,0 @@ -import "selection"; diff --git a/src/selection/insert.js b/src/selection/insert.js deleted file mode 100644 index c3b77e82ab6fcf..00000000000000 --- a/src/selection/insert.js +++ /dev/null @@ -1,9 +0,0 @@ -import "selection"; - -d3_selectionPrototype.insert = function(name, before) { - name = d3_selection_creator(name); - before = d3_selection_selector(before); - return this.select(function() { - return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments)); - }); -}; diff --git a/src/selection/interrupt.js b/src/selection/interrupt.js deleted file mode 100644 index 1588721af2d9c3..00000000000000 --- a/src/selection/interrupt.js +++ /dev/null @@ -1,11 +0,0 @@ -// import "../transition/transition"; -import "selection"; - -d3_selectionPrototype.interrupt = function() { - return this.each(d3_selection_interrupt); -}; - -function d3_selection_interrupt() { - var lock = this.__transition__; - if (lock) ++lock.active; -} diff --git a/src/selection/node.js b/src/selection/node.js deleted file mode 100644 index 9c9be4d82accbf..00000000000000 --- a/src/selection/node.js +++ /dev/null @@ -1,11 +0,0 @@ -import "selection"; - -d3_selectionPrototype.node = function() { - for (var j = 0, m = this.length; j < m; j++) { - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - var node = group[i]; - if (node) return node; - } - } - return null; -}; diff --git a/src/selection/on.js b/src/selection/on.js deleted file mode 100644 index 7e33585c2c598f..00000000000000 --- a/src/selection/on.js +++ /dev/null @@ -1,104 +0,0 @@ -import "../arrays/map"; -import "../core/array"; -import "../core/document"; -import "../core/noop"; -import "../event/event"; -import "../format/requote"; -import "selection"; - -d3_selectionPrototype.on = function(type, listener, capture) { - var n = arguments.length; - if (n < 3) { - - // For on(object) or on(object, boolean), the object specifies the event - // types and listeners to add or remove. The optional boolean specifies - // whether the listener captures events. - if (typeof type !== "string") { - if (n < 2) listener = false; - for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); - return this; - } - - // For on(string), return the listener for the first node. - if (n < 2) return (n = this.node()["__on" + type]) && n._; - - // For on(string, function), use the default capture. - capture = false; - } - - // Otherwise, a type, listener and capture are specified, and handled as below. - return this.each(d3_selection_on(type, listener, capture)); -}; - -function d3_selection_on(type, listener, capture) { - var name = "__on" + type, - i = type.indexOf("."), - wrap = d3_selection_onListener; - - if (i > 0) type = type.substring(0, i); - var filter = d3_selection_onFilters.get(type); - if (filter) type = filter, wrap = d3_selection_onFilter; - - function onRemove() { - var l = this[name]; - if (l) { - this.removeEventListener(type, l, l.$); - delete this[name]; - } - } - - function onAdd() { - var l = wrap(listener, d3_array(arguments)); - onRemove.call(this); - this.addEventListener(type, this[name] = l, l.$ = capture); - l._ = listener; - } - - function removeAll() { - var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), - match; - for (var name in this) { - if (match = name.match(re)) { - var l = this[name]; - this.removeEventListener(match[1], l, l.$); - delete this[name]; - } - } - } - - return i - ? listener ? onAdd : onRemove - : listener ? d3_noop : removeAll; -} - -var d3_selection_onFilters = d3.map({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}); - -d3_selection_onFilters.forEach(function(k) { - if ("on" + k in d3_document) d3_selection_onFilters.remove(k); -}); - -function d3_selection_onListener(listener, argumentz) { - return function(e) { - var o = d3.event; // Events can be reentrant (e.g., focus). - d3.event = e; - argumentz[0] = this.__data__; - try { - listener.apply(this, argumentz); - } finally { - d3.event = o; - } - }; -} - -function d3_selection_onFilter(listener, argumentz) { - var l = d3_selection_onListener(listener, argumentz); - return function(e) { - var target = this, related = e.relatedTarget; - if (!related || (related !== target && !(related.compareDocumentPosition(target) & 8))) { - l.call(target, e); - } - }; -} diff --git a/src/selection/order.js b/src/selection/order.js deleted file mode 100644 index dc537ac7dde5f2..00000000000000 --- a/src/selection/order.js +++ /dev/null @@ -1,13 +0,0 @@ -import "selection"; - -d3_selectionPrototype.order = function() { - for (var j = -1, m = this.length; ++j < m;) { - for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0;) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - return this; -}; diff --git a/src/selection/property.js b/src/selection/property.js deleted file mode 100644 index 8afcb89ad2e07d..00000000000000 --- a/src/selection/property.js +++ /dev/null @@ -1,43 +0,0 @@ -import "selection"; - -d3_selectionPrototype.property = function(name, value) { - if (arguments.length < 2) { - - // For property(string), return the property value for the first node. - if (typeof name === "string") return this.node()[name]; - - // For property(object), the object specifies the names and values of the - // properties to set or remove. The values may be functions that are - // evaluated for each element. - for (value in name) this.each(d3_selection_property(value, name[value])); - return this; - } - - // Otherwise, both a name and a value are specified, and are handled as below. - return this.each(d3_selection_property(name, value)); -}; - -function d3_selection_property(name, value) { - - // For property(name, null), remove the property with the specified name. - function propertyNull() { - delete this[name]; - } - - // For property(name, string), set the property with the specified name. - function propertyConstant() { - this[name] = value; - } - - // For property(name, function), evaluate the function for each element, and - // set or remove the property as appropriate. - function propertyFunction() { - var x = value.apply(this, arguments); - if (x == null) delete this[name]; - else this[name] = x; - } - - return value == null - ? propertyNull : (typeof value === "function" - ? propertyFunction : propertyConstant); -} diff --git a/src/selection/remove.js b/src/selection/remove.js deleted file mode 100644 index 4ef833141a6c24..00000000000000 --- a/src/selection/remove.js +++ /dev/null @@ -1,11 +0,0 @@ -import "selection"; - -// TODO remove(selector)? -// TODO remove(node)? -// TODO remove(function)? -d3_selectionPrototype.remove = function() { - return this.each(function() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - }); -}; diff --git a/src/selection/select.js b/src/selection/select.js deleted file mode 100644 index 8c1dcdee99d0ab..00000000000000 --- a/src/selection/select.js +++ /dev/null @@ -1,32 +0,0 @@ -import "selection"; - -d3_selectionPrototype.select = function(selector) { - var subgroups = [], - subgroup, - subnode, - group, - node; - - selector = d3_selection_selector(selector); - - for (var j = -1, m = this.length; ++j < m;) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = -1, n = group.length; ++i < n;) { - if (node = group[i]) { - subgroup.push(subnode = selector.call(node, node.__data__, i, j)); - if (subnode && "__data__" in node) subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - - return d3_selection(subgroups); -}; - -function d3_selection_selector(selector) { - return typeof selector === "function" ? selector : function() { - return d3_select(selector, this); - }; -} diff --git a/src/selection/selectAll.js b/src/selection/selectAll.js deleted file mode 100644 index 7072f8832496f0..00000000000000 --- a/src/selection/selectAll.js +++ /dev/null @@ -1,27 +0,0 @@ -import "../core/array"; -import "selection"; - -d3_selectionPrototype.selectAll = function(selector) { - var subgroups = [], - subgroup, - node; - - selector = d3_selection_selectorAll(selector); - - for (var j = -1, m = this.length; ++j < m;) { - for (var group = this[j], i = -1, n = group.length; ++i < n;) { - if (node = group[i]) { - subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); - subgroup.parentNode = node; - } - } - } - - return d3_selection(subgroups); -}; - -function d3_selection_selectorAll(selector) { - return typeof selector === "function" ? selector : function() { - return d3_selectAll(selector, this); - }; -} diff --git a/src/selection/selection.js b/src/selection/selection.js deleted file mode 100644 index 9efafc5fc5ed06..00000000000000 --- a/src/selection/selection.js +++ /dev/null @@ -1,69 +0,0 @@ -import "../core/array"; -import "../core/document"; -import "../core/subclass"; -import "../core/vendor"; - -function d3_selection(groups) { - d3_subclass(groups, d3_selectionPrototype); - return groups; -} - -var d3_select = function(s, n) { return n.querySelector(s); }, - d3_selectAll = function(s, n) { return n.querySelectorAll(s); }, - d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], - d3_selectMatches = function(n, s) { return d3_selectMatcher.call(n, s); }; - -// Prefer Sizzle, if available. -if (typeof Sizzle === "function") { - d3_select = function(s, n) { return Sizzle(s, n)[0] || null; }; - d3_selectAll = function(s, n) { return Sizzle.uniqueSort(Sizzle(s, n)); }; - d3_selectMatches = Sizzle.matchesSelector; -} - -d3.selection = function() { - return d3_selectionRoot; -}; - -var d3_selectionPrototype = d3.selection.prototype = []; - -import "select"; -import "selectAll"; -import "attr"; -import "classed"; -import "style"; -import "property"; -import "text"; -import "html"; -import "append"; -import "insert"; -import "remove"; -import "data"; -import "datum"; -import "filter"; -import "order"; -import "sort"; -import "on"; -import "each"; -import "call"; -import "empty"; -import "node"; -import "size"; -import "enter"; - -import "transition"; -import "interrupt"; - -// TODO fast singleton implementation? -d3.select = function(node) { - var group = [typeof node === "string" ? d3_select(node, d3_document) : node]; - group.parentNode = d3_documentElement; - return d3_selection([group]); -}; - -d3.selectAll = function(nodes) { - var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); - group.parentNode = d3_documentElement; - return d3_selection([group]); -}; - -var d3_selectionRoot = d3.select(d3_documentElement); diff --git a/src/selection/size.js b/src/selection/size.js deleted file mode 100644 index 3756547e2241f9..00000000000000 --- a/src/selection/size.js +++ /dev/null @@ -1,7 +0,0 @@ -import "selection"; - -d3_selectionPrototype.size = function() { - var n = 0; - this.each(function() { ++n; }); - return n; -}; diff --git a/src/selection/sort.js b/src/selection/sort.js deleted file mode 100644 index 3b596f7b1a3d42..00000000000000 --- a/src/selection/sort.js +++ /dev/null @@ -1,15 +0,0 @@ -import "../arrays/ascending"; -import "selection"; - -d3_selectionPrototype.sort = function(comparator) { - comparator = d3_selection_sortComparator.apply(this, arguments); - for (var j = -1, m = this.length; ++j < m;) this[j].sort(comparator); - return this.order(); -}; - -function d3_selection_sortComparator(comparator) { - if (!arguments.length) comparator = d3.ascending; - return function(a, b) { - return a && b ? comparator(a.__data__, b.__data__) : !a - !b; - }; -} diff --git a/src/selection/style.js b/src/selection/style.js deleted file mode 100644 index 1c6736e79d623f..00000000000000 --- a/src/selection/style.js +++ /dev/null @@ -1,56 +0,0 @@ -import "../core/document"; -import "selection"; - -d3_selectionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - - // For style(object) or style(object, string), the object specifies the - // names and values of the attributes to set or remove. The values may be - // functions that are evaluated for each element. The optional string - // specifies the priority. - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); - return this; - } - - // For style(string), return the computed style value for the first node. - if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); - - // For style(string, string) or style(string, function), use the default - // priority. The priority is ignored for style(string, null). - priority = ""; - } - - // Otherwise, a name, value and priority are specified, and handled as below. - return this.each(d3_selection_style(name, value, priority)); -}; - -function d3_selection_style(name, value, priority) { - - // For style(name, null) or style(name, null, priority), remove the style - // property with the specified name. The priority is ignored. - function styleNull() { - this.style.removeProperty(name); - } - - // For style(name, string) or style(name, string, priority), set the style - // property with the specified name, using the specified priority. - function styleConstant() { - this.style.setProperty(name, value, priority); - } - - // For style(name, function) or style(name, function, priority), evaluate the - // function for each element, and set or remove the style property as - // appropriate. When setting, use the specified priority. - function styleFunction() { - var x = value.apply(this, arguments); - if (x == null) this.style.removeProperty(name); - else this.style.setProperty(name, x, priority); - } - - return value == null - ? styleNull : (typeof value === "function" - ? styleFunction : styleConstant); -} diff --git a/src/selection/text.js b/src/selection/text.js deleted file mode 100644 index 3daf802b98fa92..00000000000000 --- a/src/selection/text.js +++ /dev/null @@ -1,10 +0,0 @@ -import "selection"; - -d3_selectionPrototype.text = function(value) { - return arguments.length - ? this.each(typeof value === "function" - ? function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; } : value == null - ? function() { this.textContent = ""; } - : function() { this.textContent = value; }) - : this.node().textContent; -}; diff --git a/src/selection/transition.js b/src/selection/transition.js deleted file mode 100644 index 339fbd83c112e6..00000000000000 --- a/src/selection/transition.js +++ /dev/null @@ -1,20 +0,0 @@ -// import "../transition/transition"; -import "selection"; - -d3_selectionPrototype.transition = function() { - var id = d3_transitionInheritId || ++d3_transitionId, - subgroups = [], - subgroup, - node, - transition = d3_transitionInherit || {time: Date.now(), ease: d3_ease_cubicInOut, delay: 0, duration: 250}; - - for (var j = -1, m = this.length; ++j < m;) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n;) { - if (node = group[i]) d3_transitionNode(node, i, id, transition); - subgroup.push(node); - } - } - - return d3_transition(subgroups, id); -}; diff --git a/src/start.js b/src/start.js deleted file mode 100644 index d25a51fe3278fd..00000000000000 --- a/src/start.js +++ /dev/null @@ -1,2 +0,0 @@ -d3 = (function(){ - var d3 = {version: "3.3.5"}; // semver diff --git a/src/svg/arc.js b/src/svg/arc.js deleted file mode 100644 index ac15698eaf24b3..00000000000000 --- a/src/svg/arc.js +++ /dev/null @@ -1,99 +0,0 @@ -import "../core/functor"; -import "../math/trigonometry"; -import "svg"; - -d3.svg.arc = function() { - var innerRadius = d3_svg_arcInnerRadius, - outerRadius = d3_svg_arcOuterRadius, - startAngle = d3_svg_arcStartAngle, - endAngle = d3_svg_arcEndAngle; - - function arc() { - var r0 = innerRadius.apply(this, arguments), - r1 = outerRadius.apply(this, arguments), - a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, - a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, - da = (a1 < a0 && (da = a0, a0 = a1, a1 = da), a1 - a0), - df = da < π ? "0" : "1", - c0 = Math.cos(a0), - s0 = Math.sin(a0), - c1 = Math.cos(a1), - s1 = Math.sin(a1); - return da >= d3_svg_arcMax - ? (r0 - ? "M0," + r1 - + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1) - + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 - + "M0," + r0 - + "A" + r0 + "," + r0 + " 0 1,0 0," + (-r0) - + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 - + "Z" - : "M0," + r1 - + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1) - + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 - + "Z") - : (r0 - ? "M" + r1 * c0 + "," + r1 * s0 - + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 - + "L" + r0 * c1 + "," + r0 * s1 - + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 - + "Z" - : "M" + r1 * c0 + "," + r1 * s0 - + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 - + "L0,0" - + "Z"); - } - - arc.innerRadius = function(v) { - if (!arguments.length) return innerRadius; - innerRadius = d3_functor(v); - return arc; - }; - - arc.outerRadius = function(v) { - if (!arguments.length) return outerRadius; - outerRadius = d3_functor(v); - return arc; - }; - - arc.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return arc; - }; - - arc.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return arc; - }; - - arc.centroid = function() { - var r = (innerRadius.apply(this, arguments) - + outerRadius.apply(this, arguments)) / 2, - a = (startAngle.apply(this, arguments) - + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; - return [Math.cos(a) * r, Math.sin(a) * r]; - }; - - return arc; -}; - -var d3_svg_arcOffset = -π / 2, - d3_svg_arcMax = 2 * π - 1e-6; - -function d3_svg_arcInnerRadius(d) { - return d.innerRadius; -} - -function d3_svg_arcOuterRadius(d) { - return d.outerRadius; -} - -function d3_svg_arcStartAngle(d) { - return d.startAngle; -} - -function d3_svg_arcEndAngle(d) { - return d.endAngle; -} diff --git a/src/svg/area-radial.js b/src/svg/area-radial.js deleted file mode 100644 index 9a5b8625c650fb..00000000000000 --- a/src/svg/area-radial.js +++ /dev/null @@ -1,14 +0,0 @@ -import "area"; -import "svg"; -import "line-radial"; - -d3.svg.area.radial = function() { - var area = d3_svg_area(d3_svg_lineRadial); - area.radius = area.x, delete area.x; - area.innerRadius = area.x0, delete area.x0; - area.outerRadius = area.x1, delete area.x1; - area.angle = area.y, delete area.y; - area.startAngle = area.y0, delete area.y0; - area.endAngle = area.y1, delete area.y1; - return area; -}; diff --git a/src/svg/area.js b/src/svg/area.js deleted file mode 100644 index 8f9f22205df7ce..00000000000000 --- a/src/svg/area.js +++ /dev/null @@ -1,120 +0,0 @@ -import "../core/functor"; -import "../core/identity"; -import "../core/true"; -import "svg"; -import "line"; - -function d3_svg_area(projection) { - var x0 = d3_svg_lineX, - x1 = d3_svg_lineX, - y0 = 0, - y1 = d3_svg_lineY, - defined = d3_true, - interpolate = d3_svg_lineLinear, - interpolateKey = interpolate.key, - interpolateReverse = interpolate, - L = "L", - tension = .7; - - function area(data) { - var segments = [], - points0 = [], - points1 = [], - i = -1, - n = data.length, - d, - fx0 = d3_functor(x0), - fy0 = d3_functor(y0), - fx1 = x0 === x1 ? function() { return x; } : d3_functor(x1), - fy1 = y0 === y1 ? function() { return y; } : d3_functor(y1), - x, - y; - - function segment() { - segments.push("M", interpolate(projection(points1), tension), - L, interpolateReverse(projection(points0.reverse()), tension), - "Z"); - } - - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points0.push([x = +fx0.call(this, d, i), y = +fy0.call(this, d, i)]); - points1.push([+fx1.call(this, d, i), +fy1.call(this, d, i)]); - } else if (points0.length) { - segment(); - points0 = []; - points1 = []; - } - } - - if (points0.length) segment(); - - return segments.length ? segments.join("") : null; - } - - area.x = function(_) { - if (!arguments.length) return x1; - x0 = x1 = _; - return area; - }; - - area.x0 = function(_) { - if (!arguments.length) return x0; - x0 = _; - return area; - }; - - area.x1 = function(_) { - if (!arguments.length) return x1; - x1 = _; - return area; - }; - - area.y = function(_) { - if (!arguments.length) return y1; - y0 = y1 = _; - return area; - }; - - area.y0 = function(_) { - if (!arguments.length) return y0; - y0 = _; - return area; - }; - - area.y1 = function(_) { - if (!arguments.length) return y1; - y1 = _; - return area; - }; - - area.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return area; - }; - - area.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; - else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - interpolateReverse = interpolate.reverse || interpolate; - L = interpolate.closed ? "M" : "L"; - return area; - }; - - area.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return area; - }; - - return area; -} - -d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; -d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; - -d3.svg.area = function() { - return d3_svg_area(d3_identity); -}; diff --git a/src/svg/axis.js b/src/svg/axis.js deleted file mode 100644 index 6f02bcea1469e6..00000000000000 --- a/src/svg/axis.js +++ /dev/null @@ -1,185 +0,0 @@ -import "../scale/linear"; -import "../scale/scale"; -import "../selection/selection"; -import "../transition/transition"; -import "svg"; - -d3.svg.axis = function() { - var scale = d3.scale.linear(), - orient = d3_svg_axisDefaultOrient, - innerTickSize = 6, - outerTickSize = 6, - tickPadding = 3, - tickArguments_ = [10], - tickValues = null, - tickFormat_; - - function axis(g) { - g.each(function() { - var g = d3.select(this); - - // Ticks, or domain values for ordinal scales. - var ticks = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain()) : tickValues, - tickFormat = tickFormat_ == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : d3_identity) : tickFormat_, - tick = g.selectAll(".tick").data(ticks, scale), - tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6), - tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(), - tickUpdate = d3.transition(tick).style("opacity", 1), - tickTransform; - - // Domain. - var range = d3_scaleRange(scale), - path = g.selectAll(".domain").data([0]), - pathUpdate = (path.enter().append("path").attr("class", "domain"), d3.transition(path)); - - // Stash a snapshot of the new scale, and retrieve the old snapshot. - var scale1 = scale.copy(), - scale0 = this.__chart__ || scale1; - this.__chart__ = scale1; - - tickEnter.append("line"); - tickEnter.append("text"); - - var lineEnter = tickEnter.select("line"), - lineUpdate = tickUpdate.select("line"), - text = tick.select("text").text(tickFormat), - textEnter = tickEnter.select("text"), - textUpdate = tickUpdate.select("text"); - - switch (orient) { - case "bottom": { - tickTransform = d3_svg_axisX; - lineEnter.attr("y2", innerTickSize); - textEnter.attr("y", Math.max(innerTickSize, 0) + tickPadding); - lineUpdate.attr("x2", 0).attr("y2", innerTickSize); - textUpdate.attr("x", 0).attr("y", Math.max(innerTickSize, 0) + tickPadding); - text.attr("dy", ".71em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize); - break; - } - case "top": { - tickTransform = d3_svg_axisX; - lineEnter.attr("y2", -innerTickSize); - textEnter.attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); - lineUpdate.attr("x2", 0).attr("y2", -innerTickSize); - textUpdate.attr("x", 0).attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); - text.attr("dy", "0em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize); - break; - } - case "left": { - tickTransform = d3_svg_axisY; - lineEnter.attr("x2", -innerTickSize); - textEnter.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)); - lineUpdate.attr("x2", -innerTickSize).attr("y2", 0); - textUpdate.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "end"); - pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize); - break; - } - case "right": { - tickTransform = d3_svg_axisY; - lineEnter.attr("x2", innerTickSize); - textEnter.attr("x", Math.max(innerTickSize, 0) + tickPadding); - lineUpdate.attr("x2", innerTickSize).attr("y2", 0); - textUpdate.attr("x", Math.max(innerTickSize, 0) + tickPadding).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "start"); - pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize); - break; - } - } - - // For ordinal scales: - // - any entering ticks are undefined in the old scale - // - any exiting ticks are undefined in the new scale - // Therefore, we only need to transition updating ticks. - if (scale.rangeBand) { - var dx = scale1.rangeBand() / 2, x = function(d) { return scale1(d) + dx; }; - tickEnter.call(tickTransform, x); - tickUpdate.call(tickTransform, x); - } - - // For quantitative scales: - // - enter new ticks from the old scale - // - exit old ticks to the new scale - else { - tickEnter.call(tickTransform, scale0); - tickUpdate.call(tickTransform, scale1); - tickExit.call(tickTransform, scale1); - } - }); - } - - axis.scale = function(x) { - if (!arguments.length) return scale; - scale = x; - return axis; - }; - - axis.orient = function(x) { - if (!arguments.length) return orient; - orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; - return axis; - }; - - axis.ticks = function() { - if (!arguments.length) return tickArguments_; - tickArguments_ = arguments; - return axis; - }; - - axis.tickValues = function(x) { - if (!arguments.length) return tickValues; - tickValues = x; - return axis; - }; - - axis.tickFormat = function(x) { - if (!arguments.length) return tickFormat_; - tickFormat_ = x; - return axis; - }; - - axis.tickSize = function(x) { - var n = arguments.length; - if (!n) return innerTickSize; - innerTickSize = +x; - outerTickSize = +arguments[n - 1]; - return axis; - }; - - axis.innerTickSize = function(x) { - if (!arguments.length) return innerTickSize; - innerTickSize = +x; - return axis; - }; - - axis.outerTickSize = function(x) { - if (!arguments.length) return outerTickSize; - outerTickSize = +x; - return axis; - }; - - axis.tickPadding = function(x) { - if (!arguments.length) return tickPadding; - tickPadding = +x; - return axis; - }; - - axis.tickSubdivide = function() { - return arguments.length && axis; - }; - - return axis; -}; - -var d3_svg_axisDefaultOrient = "bottom", - d3_svg_axisOrients = {top: 1, right: 1, bottom: 1, left: 1}; - -function d3_svg_axisX(selection, x) { - selection.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; }); -} - -function d3_svg_axisY(selection, y) { - selection.attr("transform", function(d) { return "translate(0," + y(d) + ")"; }); -} diff --git a/src/svg/brush.js b/src/svg/brush.js deleted file mode 100644 index 3f91dd32b975c4..00000000000000 --- a/src/svg/brush.js +++ /dev/null @@ -1,430 +0,0 @@ -import "../core/document"; -import "../core/rebind"; -import "../event/dispatch"; -import "../event/drag"; -import "../event/event"; -import "../event/mouse"; -import "../event/touches"; -import "../scale/scale"; -import "../selection/selection"; -import "svg"; - -d3.svg.brush = function() { - var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), - x = null, // x-scale, optional - y = null, // y-scale, optional - xExtent = [0, 0], // [x0, x1] in integer pixels - yExtent = [0, 0], // [y0, y1] in integer pixels - xExtentDomain, // x-extent in data space - yExtentDomain, // y-extent in data space - xClamp = true, // whether to clamp the x-extent to the range - yClamp = true, // whether to clamp the y-extent to the range - resizes = d3_svg_brushResizes[0]; - - function brush(g) { - g.each(function() { - - // Prepare the brush container for events. - var g = d3.select(this) - .style("pointer-events", "all") - .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") - .on("mousedown.brush", brushstart) - .on("touchstart.brush", brushstart); - - // An invisible, mouseable area for starting a new brush. - var background = g.selectAll(".background") - .data([0]); - - background.enter().append("rect") - .attr("class", "background") - .style("visibility", "hidden") - .style("cursor", "crosshair"); - - // The visible brush extent; style this as you like! - g.selectAll(".extent") - .data([0]) - .enter().append("rect") - .attr("class", "extent") - .style("cursor", "move"); - - // More invisible rects for resizing the extent. - var resize = g.selectAll(".resize") - .data(resizes, d3_identity); - - // Remove any superfluous resizers. - resize.exit().remove(); - - resize.enter().append("g") - .attr("class", function(d) { return "resize " + d; }) - .style("cursor", function(d) { return d3_svg_brushCursor[d]; }) - .append("rect") - .attr("x", function(d) { return /[ew]$/.test(d) ? -3 : null; }) - .attr("y", function(d) { return /^[ns]/.test(d) ? -3 : null; }) - .attr("width", 6) - .attr("height", 6) - .style("visibility", "hidden"); - - // Show or hide the resizers. - resize.style("display", brush.empty() ? "none" : null); - - // When called on a transition, use a transition to update. - var gUpdate = d3.transition(g), - backgroundUpdate = d3.transition(background), - range; - - // Initialize the background to fill the defined range. - // If the range isn't defined, you can post-process. - if (x) { - range = d3_scaleRange(x); - backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); - redrawX(gUpdate); - } - if (y) { - range = d3_scaleRange(y); - backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); - redrawY(gUpdate); - } - redraw(gUpdate); - }); - } - - brush.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), - extent1 = {x: xExtent, y: yExtent, i: xExtentDomain, j: yExtentDomain}, - extent0 = this.__chart__ || extent1; - this.__chart__ = extent1; - if (d3_transitionInheritId) { - d3.select(this).transition() - .each("start.brush", function() { - xExtentDomain = extent0.i; // pre-transition state - yExtentDomain = extent0.j; - xExtent = extent0.x; - yExtent = extent0.y; - event_({type: "brushstart"}); - }) - .tween("brush:brush", function() { - var xi = d3_interpolateArray(xExtent, extent1.x), - yi = d3_interpolateArray(yExtent, extent1.y); - xExtentDomain = yExtentDomain = null; // transition state - return function(t) { - xExtent = extent1.x = xi(t); - yExtent = extent1.y = yi(t); - event_({type: "brush", mode: "resize"}); - }; - }) - .each("end.brush", function() { - xExtentDomain = extent1.i; // post-transition state - yExtentDomain = extent1.j; - event_({type: "brush", mode: "resize"}); - event_({type: "brushend"}); - }); - } else { - event_({type: "brushstart"}); - event_({type: "brush", mode: "resize"}); - event_({type: "brushend"}); - } - }); - }; - - function redraw(g) { - g.selectAll(".resize").attr("transform", function(d) { - return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; - }); - } - - function redrawX(g) { - g.select(".extent").attr("x", xExtent[0]); - g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); - } - - function redrawY(g) { - g.select(".extent").attr("y", yExtent[0]); - g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); - } - - function brushstart() { - var target = this, - eventTarget = d3.select(d3.event.target), - event_ = event.of(target, arguments), - g = d3.select(target), - resizing = eventTarget.datum(), - resizingX = !/^(n|s)$/.test(resizing) && x, - resizingY = !/^(e|w)$/.test(resizing) && y, - dragging = eventTarget.classed("extent"), - dragRestore = d3_event_dragSuppress(), - center, - origin = d3.mouse(target), - offset; - - var w = d3.select(d3_window) - .on("keydown.brush", keydown) - .on("keyup.brush", keyup); - - if (d3.event.changedTouches) { - w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); - } else { - w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); - } - - // Interrupt the transition, if any. - g.interrupt().selectAll("*").interrupt(); - - // If the extent was clicked on, drag rather than brush; - // store the point between the mouse and extent origin instead. - if (dragging) { - origin[0] = xExtent[0] - origin[0]; - origin[1] = yExtent[0] - origin[1]; - } - - // If a resizer was clicked on, record which side is to be resized. - // Also, set the origin to the opposite side. - else if (resizing) { - var ex = +/w$/.test(resizing), - ey = +/^n/.test(resizing); - offset = [xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1]]; - origin[0] = xExtent[ex]; - origin[1] = yExtent[ey]; - } - - // If the ALT key is down when starting a brush, the center is at the mouse. - else if (d3.event.altKey) center = origin.slice(); - - // Propagate the active cursor to the body for the drag duration. - g.style("pointer-events", "none").selectAll(".resize").style("display", null); - d3.select("body").style("cursor", eventTarget.style("cursor")); - - // Notify listeners. - event_({type: "brushstart"}); - brushmove(); - - function keydown() { - if (d3.event.keyCode == 32) { - if (!dragging) { - center = null; - origin[0] -= xExtent[1]; - origin[1] -= yExtent[1]; - dragging = 2; - } - d3_eventPreventDefault(); - } - } - - function keyup() { - if (d3.event.keyCode == 32 && dragging == 2) { - origin[0] += xExtent[1]; - origin[1] += yExtent[1]; - dragging = 0; - d3_eventPreventDefault(); - } - } - - function brushmove() { - var point = d3.mouse(target), - moved = false; - - // Preserve the offset for thick resizers. - if (offset) { - point[0] += offset[0]; - point[1] += offset[1]; - } - - if (!dragging) { - - // If needed, determine the center from the current extent. - if (d3.event.altKey) { - if (!center) center = [(xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2]; - - // Update the origin, for when the ALT key is released. - origin[0] = xExtent[+(point[0] < center[0])]; - origin[1] = yExtent[+(point[1] < center[1])]; - } - - // When the ALT key is released, we clear the center. - else center = null; - } - - // Update the brush extent for each dimension. - if (resizingX && move1(point, x, 0)) { - redrawX(g); - moved = true; - } - if (resizingY && move1(point, y, 1)) { - redrawY(g); - moved = true; - } - - // Final redraw and notify listeners. - if (moved) { - redraw(g); - event_({type: "brush", mode: dragging ? "move" : "resize"}); - } - } - - function move1(point, scale, i) { - var range = d3_scaleRange(scale), - r0 = range[0], - r1 = range[1], - position = origin[i], - extent = i ? yExtent : xExtent, - size = extent[1] - extent[0], - min, - max; - - // When dragging, reduce the range by the extent size and position. - if (dragging) { - r0 -= position; - r1 -= size + position; - } - - // Clamp the point (unless clamp set to false) so that the extent fits within the range extent. - min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; - - // Compute the new extent bounds. - if (dragging) { - max = (min += position) + size; - } else { - - // If the ALT key is pressed, then preserve the center of the extent. - if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); - - // Compute the min and max of the position and point. - if (position < min) { - max = min; - min = position; - } else { - max = position; - } - } - - // Update the stored bounds. - if (extent[0] != min || extent[1] != max) { - if (i) yExtentDomain = null; - else xExtentDomain = null; - extent[0] = min; - extent[1] = max; - return true; - } - } - - function brushend() { - brushmove(); - - // reset the cursor styles - g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); - d3.select("body").style("cursor", null); - - w .on("mousemove.brush", null) - .on("mouseup.brush", null) - .on("touchmove.brush", null) - .on("touchend.brush", null) - .on("keydown.brush", null) - .on("keyup.brush", null); - - dragRestore(); - event_({type: "brushend"}); - } - } - - brush.x = function(z) { - if (!arguments.length) return x; - x = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; // fore! - return brush; - }; - - brush.y = function(z) { - if (!arguments.length) return y; - y = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; // fore! - return brush; - }; - - brush.clamp = function(z) { - if (!arguments.length) return x && y ? [xClamp, yClamp] : x ? xClamp : y ? yClamp : null; - if (x && y) xClamp = !!z[0], yClamp = !!z[1]; - else if (x) xClamp = !!z; - else if (y) yClamp = !!z; - return brush; - }; - - brush.extent = function(z) { - var x0, x1, y0, y1, t; - - // Invert the pixel extent to data-space. - if (!arguments.length) { - if (x) { - if (xExtentDomain) { - x0 = xExtentDomain[0], x1 = xExtentDomain[1]; - } else { - x0 = xExtent[0], x1 = xExtent[1]; - if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - } - } - if (y) { - if (yExtentDomain) { - y0 = yExtentDomain[0], y1 = yExtentDomain[1]; - } else { - y0 = yExtent[0], y1 = yExtent[1]; - if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - } - } - return x && y ? [[x0, y0], [x1, y1]] : x ? [x0, x1] : y && [y0, y1]; - } - - // Scale the data-space extent to pixels. - if (x) { - x0 = z[0], x1 = z[1]; - if (y) x0 = x0[0], x1 = x1[0]; - xExtentDomain = [x0, x1]; - if (x.invert) x0 = x(x0), x1 = x(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [x0, x1]; // copy-on-write - } - if (y) { - y0 = z[0], y1 = z[1]; - if (x) y0 = y0[1], y1 = y1[1]; - yExtentDomain = [y0, y1]; - if (y.invert) y0 = y(y0), y1 = y(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [y0, y1]; // copy-on-write - } - - return brush; - }; - - brush.clear = function() { - if (!brush.empty()) { - xExtent = [0, 0], yExtent = [0, 0]; // copy-on-write - xExtentDomain = yExtentDomain = null; - } - return brush; - }; - - brush.empty = function() { - return !!x && xExtent[0] == xExtent[1] - || !!y && yExtent[0] == yExtent[1]; - }; - - return d3.rebind(brush, event, "on"); -}; - -var d3_svg_brushCursor = { - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" -}; - -var d3_svg_brushResizes = [ - ["n", "e", "s", "w", "nw", "ne", "se", "sw"], - ["e", "w"], - ["n", "s"], - [] -]; diff --git a/src/svg/chord.js b/src/svg/chord.js deleted file mode 100644 index dff53d5862940c..00000000000000 --- a/src/svg/chord.js +++ /dev/null @@ -1,90 +0,0 @@ -import "../core/functor"; -import "../core/source"; -import "../core/target"; -import "../math/trigonometry"; -import "arc"; -import "svg"; - -d3.svg.chord = function() { - var source = d3_source, - target = d3_target, - radius = d3_svg_chordRadius, - startAngle = d3_svg_arcStartAngle, - endAngle = d3_svg_arcEndAngle; - - // TODO Allow control point to be customized. - - function chord(d, i) { - var s = subgroup(this, source, d, i), - t = subgroup(this, target, d, i); - return "M" + s.p0 - + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) - ? curve(s.r, s.p1, s.r, s.p0) - : curve(s.r, s.p1, t.r, t.p0) - + arc(t.r, t.p1, t.a1 - t.a0) - + curve(t.r, t.p1, s.r, s.p0)) - + "Z"; - } - - function subgroup(self, f, d, i) { - var subgroup = f.call(self, d, i), - r = radius.call(self, subgroup, i), - a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, - a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; - return { - r: r, - a0: a0, - a1: a1, - p0: [r * Math.cos(a0), r * Math.sin(a0)], - p1: [r * Math.cos(a1), r * Math.sin(a1)] - }; - } - - function equals(a, b) { - return a.a0 == b.a0 && a.a1 == b.a1; - } - - function arc(r, p, a) { - return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; - } - - function curve(r0, p0, r1, p1) { - return "Q 0,0 " + p1; - } - - chord.radius = function(v) { - if (!arguments.length) return radius; - radius = d3_functor(v); - return chord; - }; - - chord.source = function(v) { - if (!arguments.length) return source; - source = d3_functor(v); - return chord; - }; - - chord.target = function(v) { - if (!arguments.length) return target; - target = d3_functor(v); - return chord; - }; - - chord.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return chord; - }; - - chord.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return chord; - }; - - return chord; -}; - -function d3_svg_chordRadius(d) { - return d.radius; -} diff --git a/src/svg/diagonal-radial.js b/src/svg/diagonal-radial.js deleted file mode 100644 index 333a824b1181b7..00000000000000 --- a/src/svg/diagonal-radial.js +++ /dev/null @@ -1,26 +0,0 @@ -import "arc"; -import "diagonal"; -import "svg"; - -d3.svg.diagonal.radial = function() { - var diagonal = d3.svg.diagonal(), - projection = d3_svg_diagonalProjection, - projection_ = diagonal.projection; - - diagonal.projection = function(x) { - return arguments.length - ? projection_(d3_svg_diagonalRadialProjection(projection = x)) - : projection; - }; - - return diagonal; -}; - -function d3_svg_diagonalRadialProjection(projection) { - return function() { - var d = projection.apply(this, arguments), - r = d[0], - a = d[1] + d3_svg_arcOffset; - return [r * Math.cos(a), r * Math.sin(a)]; - }; -} diff --git a/src/svg/diagonal.js b/src/svg/diagonal.js deleted file mode 100644 index 17d15def937e8e..00000000000000 --- a/src/svg/diagonal.js +++ /dev/null @@ -1,43 +0,0 @@ -import "../core/functor"; -import "../core/source"; -import "../core/target"; -import "svg"; - -d3.svg.diagonal = function() { - var source = d3_source, - target = d3_target, - projection = d3_svg_diagonalProjection; - - function diagonal(d, i) { - var p0 = source.call(this, d, i), - p3 = target.call(this, d, i), - m = (p0.y + p3.y) / 2, - p = [p0, {x: p0.x, y: m}, {x: p3.x, y: m}, p3]; - p = p.map(projection); - return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; - } - - diagonal.source = function(x) { - if (!arguments.length) return source; - source = d3_functor(x); - return diagonal; - }; - - diagonal.target = function(x) { - if (!arguments.length) return target; - target = d3_functor(x); - return diagonal; - }; - - diagonal.projection = function(x) { - if (!arguments.length) return projection; - projection = x; - return diagonal; - }; - - return diagonal; -}; - -function d3_svg_diagonalProjection(d) { - return [d.x, d.y]; -} diff --git a/src/svg/index.js b/src/svg/index.js deleted file mode 100644 index a9201d7d49c755..00000000000000 --- a/src/svg/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import "svg"; -import "arc"; -import "line"; -import "line-radial"; -import "area"; -import "area-radial"; -import "chord"; -import "diagonal"; -import "diagonal-radial"; -import "symbol"; -import "axis"; -import "brush"; diff --git a/src/svg/line-radial.js b/src/svg/line-radial.js deleted file mode 100644 index 70db2f7f06ecb2..00000000000000 --- a/src/svg/line-radial.js +++ /dev/null @@ -1,26 +0,0 @@ -import "arc"; -import "line"; -import "svg"; - -d3.svg.line.radial = function() { - var line = d3_svg_line(d3_svg_lineRadial); - line.radius = line.x, delete line.x; - line.angle = line.y, delete line.y; - return line; -}; - -function d3_svg_lineRadial(points) { - var point, - i = -1, - n = points.length, - r, - a; - while (++i < n) { - point = points[i]; - r = point[0]; - a = point[1] + d3_svg_arcOffset; - point[0] = r * Math.cos(a); - point[1] = r * Math.sin(a); - } - return points; -} diff --git a/src/svg/line.js b/src/svg/line.js deleted file mode 100644 index f2e44aed5f8843..00000000000000 --- a/src/svg/line.js +++ /dev/null @@ -1,439 +0,0 @@ -import "../arrays/map"; -import "../core/functor"; -import "../core/identity"; -import "../core/true"; -import "svg"; - -function d3_svg_line(projection) { - var x = d3_svg_lineX, - y = d3_svg_lineY, - defined = d3_true, - interpolate = d3_svg_lineLinear, - interpolateKey = interpolate.key, - tension = .7; - - function line(data) { - var segments = [], - points = [], - i = -1, - n = data.length, - d, - fx = d3_functor(x), - fy = d3_functor(y); - - function segment() { - segments.push("M", interpolate(projection(points), tension)); - } - - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points.push([+fx.call(this, d, i), +fy.call(this, d, i)]); - } else if (points.length) { - segment(); - points = []; - } - } - - if (points.length) segment(); - - return segments.length ? segments.join("") : null; - } - - line.x = function(_) { - if (!arguments.length) return x; - x = _; - return line; - }; - - line.y = function(_) { - if (!arguments.length) return y; - y = _; - return line; - }; - - line.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return line; - }; - - line.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; - else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - return line; - }; - - line.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return line; - }; - - return line; -} - -d3.svg.line = function() { - return d3_svg_line(d3_identity); -}; - -// The default `x` property, which references d[0]. -function d3_svg_lineX(d) { - return d[0]; -} - -// The default `y` property, which references d[1]. -function d3_svg_lineY(d) { - return d[1]; -} - -// The various interpolators supported by the `line` class. -var d3_svg_lineInterpolators = d3.map({ - "linear": d3_svg_lineLinear, - "linear-closed": d3_svg_lineLinearClosed, - "step": d3_svg_lineStep, - "step-before": d3_svg_lineStepBefore, - "step-after": d3_svg_lineStepAfter, - "basis": d3_svg_lineBasis, - "basis-open": d3_svg_lineBasisOpen, - "basis-closed": d3_svg_lineBasisClosed, - "bundle": d3_svg_lineBundle, - "cardinal": d3_svg_lineCardinal, - "cardinal-open": d3_svg_lineCardinalOpen, - "cardinal-closed": d3_svg_lineCardinalClosed, - "monotone": d3_svg_lineMonotone -}); - -d3_svg_lineInterpolators.forEach(function(key, value) { - value.key = key; - value.closed = /-closed$/.test(key); -}); - -// Linear interpolation; generates "L" commands. -function d3_svg_lineLinear(points) { - return points.join("L"); -} - -function d3_svg_lineLinearClosed(points) { - return d3_svg_lineLinear(points) + "Z"; -} - -// Step interpolation; generates "H" and "V" commands. -function d3_svg_lineStep(points) { - var i = 0, - n = points.length, - p = points[0], - path = [p[0], ",", p[1]]; - while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); - if (n > 1) path.push("H", p[0]); - return path.join(""); -} - -// Step interpolation; generates "H" and "V" commands. -function d3_svg_lineStepBefore(points) { - var i = 0, - n = points.length, - p = points[0], - path = [p[0], ",", p[1]]; - while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); - return path.join(""); -} - -// Step interpolation; generates "H" and "V" commands. -function d3_svg_lineStepAfter(points) { - var i = 0, - n = points.length, - p = points[0], - path = [p[0], ",", p[1]]; - while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); - return path.join(""); -} - -// Open cardinal spline interpolation; generates "C" commands. -function d3_svg_lineCardinalOpen(points, tension) { - return points.length < 4 - ? d3_svg_lineLinear(points) - : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), - d3_svg_lineCardinalTangents(points, tension)); -} - -// Closed cardinal spline interpolation; generates "C" commands. -function d3_svg_lineCardinalClosed(points, tension) { - return points.length < 3 - ? d3_svg_lineLinear(points) - : points[0] + d3_svg_lineHermite((points.push(points[0]), points), - d3_svg_lineCardinalTangents([points[points.length - 2]] - .concat(points, [points[1]]), tension)); -} - -// Cardinal spline interpolation; generates "C" commands. -function d3_svg_lineCardinal(points, tension) { - return points.length < 3 - ? d3_svg_lineLinear(points) - : points[0] + d3_svg_lineHermite(points, - d3_svg_lineCardinalTangents(points, tension)); -} - -// Hermite spline construction; generates "C" commands. -function d3_svg_lineHermite(points, tangents) { - if (tangents.length < 1 - || (points.length != tangents.length - && points.length != tangents.length + 2)) { - return d3_svg_lineLinear(points); - } - - var quad = points.length != tangents.length, - path = "", - p0 = points[0], - p = points[1], - t0 = tangents[0], - t = t0, - pi = 1; - - if (quad) { - path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) - + "," + p[0] + "," + p[1]; - p0 = points[1]; - pi = 2; - } - - if (tangents.length > 1) { - t = tangents[1]; - p = points[pi]; - pi++; - path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) - + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) - + "," + p[0] + "," + p[1]; - for (var i = 2; i < tangents.length; i++, pi++) { - p = points[pi]; - t = tangents[i]; - path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) - + "," + p[0] + "," + p[1]; - } - } - - if (quad) { - var lp = points[pi]; - path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) - + "," + lp[0] + "," + lp[1]; - } - - return path; -} - -// Generates tangents for a cardinal spline. -function d3_svg_lineCardinalTangents(points, tension) { - var tangents = [], - a = (1 - tension) / 2, - p0, - p1 = points[0], - p2 = points[1], - i = 1, - n = points.length; - while (++i < n) { - p0 = p1; - p1 = p2; - p2 = points[i]; - tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]); - } - return tangents; -} - -// B-spline interpolation; generates "C" commands. -function d3_svg_lineBasis(points) { - if (points.length < 3) return d3_svg_lineLinear(points); - var i = 1, - n = points.length, - pi = points[0], - x0 = pi[0], - y0 = pi[1], - px = [x0, x0, x0, (pi = points[1])[0]], - py = [y0, y0, y0, pi[1]], - path = [x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)]; - points.push(points[n - 1]); - while (++i <= n) { - pi = points[i]; - px.shift(); px.push(pi[0]); - py.shift(); py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - points.pop(); - path.push("L", pi); - return path.join(""); -} - -// Open B-spline interpolation; generates "C" commands. -function d3_svg_lineBasisOpen(points) { - if (points.length < 4) return d3_svg_lineLinear(points); - var path = [], - i = -1, - n = points.length, - pi, - px = [0], - py = [0]; - while (++i < 3) { - pi = points[i]; - px.push(pi[0]); - py.push(pi[1]); - } - path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) - + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); - --i; while (++i < n) { - pi = points[i]; - px.shift(); px.push(pi[0]); - py.shift(); py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); -} - -// Closed B-spline interpolation; generates "C" commands. -function d3_svg_lineBasisClosed(points) { - var path, - i = -1, - n = points.length, - m = n + 4, - pi, - px = [], - py = []; - while (++i < 4) { - pi = points[i % n]; - px.push(pi[0]); - py.push(pi[1]); - } - path = [ - d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", - d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) - ]; - --i; while (++i < m) { - pi = points[i % n]; - px.shift(); px.push(pi[0]); - py.shift(); py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); -} - -function d3_svg_lineBundle(points, tension) { - var n = points.length - 1; - if (n) { - var x0 = points[0][0], - y0 = points[0][1], - dx = points[n][0] - x0, - dy = points[n][1] - y0, - i = -1, - p, - t; - while (++i <= n) { - p = points[i]; - t = i / n; - p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); - p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); - } - } - return d3_svg_lineBasis(points); -} - -// Returns the dot product of the given four-element vectors. -function d3_svg_lineDot4(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; -} - -// Matrix to transform basis (b-spline) control points to bezier -// control points. Derived from FvD 11.2.8. -var d3_svg_lineBasisBezier1 = [0, 2/3, 1/3, 0], - d3_svg_lineBasisBezier2 = [0, 1/3, 2/3, 0], - d3_svg_lineBasisBezier3 = [0, 1/6, 2/3, 1/6]; - -// Pushes a "C" Bézier curve onto the specified path array, given the -// two specified four-element arrays which define the control points. -function d3_svg_lineBasisBezier(path, x, y) { - path.push( - "C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), - ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), - ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), - ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), - ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), - ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); -} - -// Computes the slope from points p0 to p1. -function d3_svg_lineSlope(p0, p1) { - return (p1[1] - p0[1]) / (p1[0] - p0[0]); -} - -// Compute three-point differences for the given points. -// http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference -function d3_svg_lineFiniteDifferences(points) { - var i = 0, - j = points.length - 1, - m = [], - p0 = points[0], - p1 = points[1], - d = m[0] = d3_svg_lineSlope(p0, p1); - while (++i < j) { - m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; - } - m[i] = d; - return m; -} - -// Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite -// interpolation. Returns an array of tangent vectors. For details, see -// http://en.wikipedia.org/wiki/Monotone_cubic_interpolation -function d3_svg_lineMonotoneTangents(points) { - var tangents = [], - d, - a, - b, - s, - m = d3_svg_lineFiniteDifferences(points), - i = -1, - j = points.length - 1; - - // The first two steps are done by computing finite-differences: - // 1. Compute the slopes of the secant lines between successive points. - // 2. Initialize the tangents at every point as the average of the secants. - - // Then, for each segment… - while (++i < j) { - d = d3_svg_lineSlope(points[i], points[i + 1]); - - // 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set - // mk = m{k + 1} = 0 as the spline connecting these points must be flat to - // preserve monotonicity. Ignore step 4 and 5 for those k. - - if (Math.abs(d) < 1e-6) { - m[i] = m[i + 1] = 0; - } else { - // 4. Let ak = mk / dk and bk = m{k + 1} / dk. - a = m[i] / d; - b = m[i + 1] / d; - - // 5. Prevent overshoot and ensure monotonicity by restricting the - // magnitude of vector to a circle of radius 3. - s = a * a + b * b; - if (s > 9) { - s = d * 3 / Math.sqrt(s); - m[i] = s * a; - m[i + 1] = s * b; - } - } - } - - // Compute the normalized tangent vector from the slopes. Note that if x is - // not monotonic, it's possible that the slope will be infinite, so we protect - // against NaN by setting the coordinate to zero. - i = -1; while (++i <= j) { - s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); - tangents.push([s || 0, m[i] * s || 0]); - } - - return tangents; -} - -function d3_svg_lineMonotone(points) { - return points.length < 3 - ? d3_svg_lineLinear(points) - : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); -} diff --git a/src/svg/svg.js b/src/svg/svg.js deleted file mode 100644 index 3749248210fd21..00000000000000 --- a/src/svg/svg.js +++ /dev/null @@ -1 +0,0 @@ -d3.svg = {}; diff --git a/src/svg/symbol.js b/src/svg/symbol.js deleted file mode 100644 index 6ac58bf8e11e37..00000000000000 --- a/src/svg/symbol.js +++ /dev/null @@ -1,105 +0,0 @@ -import "../arrays/map"; -import "../core/functor"; -import "../math/trigonometry"; -import "svg"; - -d3.svg.symbol = function() { - var type = d3_svg_symbolType, - size = d3_svg_symbolSize; - - function symbol(d, i) { - return (d3_svg_symbols.get(type.call(this, d, i)) - || d3_svg_symbolCircle) - (size.call(this, d, i)); - } - - symbol.type = function(x) { - if (!arguments.length) return type; - type = d3_functor(x); - return symbol; - }; - - // size of symbol in square pixels - symbol.size = function(x) { - if (!arguments.length) return size; - size = d3_functor(x); - return symbol; - }; - - return symbol; -}; - -function d3_svg_symbolSize() { - return 64; -} - -function d3_svg_symbolType() { - return "circle"; -} - -function d3_svg_symbolCircle(size) { - var r = Math.sqrt(size / π); - return "M0," + r - + "A" + r + "," + r + " 0 1,1 0," + (-r) - + "A" + r + "," + r + " 0 1,1 0," + r - + "Z"; -} - -// TODO cross-diagonal? -var d3_svg_symbols = d3.map({ - "circle": d3_svg_symbolCircle, - "cross": function(size) { - var r = Math.sqrt(size / 5) / 2; - return "M" + -3 * r + "," + -r - + "H" + -r - + "V" + -3 * r - + "H" + r - + "V" + -r - + "H" + 3 * r - + "V" + r - + "H" + r - + "V" + 3 * r - + "H" + -r - + "V" + r - + "H" + -3 * r - + "Z"; - }, - "diamond": function(size) { - var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), - rx = ry * d3_svg_symbolTan30; - return "M0," + -ry - + "L" + rx + ",0" - + " 0," + ry - + " " + -rx + ",0" - + "Z"; - }, - "square": function(size) { - var r = Math.sqrt(size) / 2; - return "M" + -r + "," + -r - + "L" + r + "," + -r - + " " + r + "," + r - + " " + -r + "," + r - + "Z"; - }, - "triangle-down": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), - ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + ry - + "L" + rx +"," + -ry - + " " + -rx + "," + -ry - + "Z"; - }, - "triangle-up": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), - ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + -ry - + "L" + rx +"," + ry - + " " + -rx + "," + ry - + "Z"; - } -}); - -d3.svg.symbolTypes = d3_svg_symbols.keys(); - -var d3_svg_symbolSqrt3 = Math.sqrt(3), - d3_svg_symbolTan30 = Math.tan(30 * d3_radians); diff --git a/src/time/day.js b/src/time/day.js deleted file mode 100644 index 3b8e7dec0c267e..00000000000000 --- a/src/time/day.js +++ /dev/null @@ -1,21 +0,0 @@ -import "interval"; -import "time"; -import "year"; - -d3_time.day = d3_time_interval(function(date) { - var day = new d3_date(2000, 0); - day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - return day; -}, function(date, offset) { - date.setDate(date.getDate() + offset); -}, function(date) { - return date.getDate() - 1; -}); - -d3_time.days = d3_time.day.range; -d3_time.days.utc = d3_time.day.utc.range; - -d3_time.dayOfYear = function(date) { - var year = d3_time.year(date); - return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); -}; diff --git a/src/time/format-iso.js b/src/time/format-iso.js deleted file mode 100644 index 300de40dad85f6..00000000000000 --- a/src/time/format-iso.js +++ /dev/null @@ -1,20 +0,0 @@ -import "format"; -import "format-utc"; -import "time"; - -var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); - -d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") - ? d3_time_formatIsoNative - : d3_time_formatIso; - -function d3_time_formatIsoNative(date) { - return date.toISOString(); -} - -d3_time_formatIsoNative.parse = function(string) { - var date = new Date(string); - return isNaN(date) ? null : date; -}; - -d3_time_formatIsoNative.toString = d3_time_formatIso.toString; diff --git a/src/time/format-locale.js b/src/time/format-locale.js deleted file mode 100644 index 934673ac6fd9aa..00000000000000 --- a/src/time/format-locale.js +++ /dev/null @@ -1,10 +0,0 @@ -// The date and time format (%c), date format (%x) and time format (%X). -var d3_time_formatDateTime = {d_t_fmt}, - d3_time_formatDate = {d_fmt}, - d3_time_formatTime = {t_fmt}; - -// The weekday and month names. -var d3_time_days = {day}, - d3_time_dayAbbreviations = {abday}, - d3_time_months = {mon}, - d3_time_monthAbbreviations = {abmon}; diff --git a/src/time/format-localized.js b/src/time/format-localized.js deleted file mode 100644 index 5262b9494db22d..00000000000000 --- a/src/time/format-localized.js +++ /dev/null @@ -1,11 +0,0 @@ -// The date and time format (%c), date format (%x) and time format (%X). -var d3_time_formatDateTime = "%a %b %e %X %Y", - d3_time_formatDate = "%m/%d/%Y", - d3_time_formatTime = "%H:%M:%S"; - -// The weekday and month names. -var d3_time_days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], - d3_time_dayAbbreviations = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], - d3_time_months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - d3_time_monthAbbreviations = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - diff --git a/src/time/format-utc.js b/src/time/format-utc.js deleted file mode 100644 index 7d2782d1bdfeee..00000000000000 --- a/src/time/format-utc.js +++ /dev/null @@ -1,33 +0,0 @@ -import "format"; -import "time"; - -d3_time_format.utc = d3_time_formatUtc; - -function d3_time_formatUtc(template) { - var local = d3_time_format(template); - - function format(date) { - try { - d3_date = d3_date_utc; - var utc = new d3_date(); - utc._ = date; - return local(utc); - } finally { - d3_date = Date; - } - } - - format.parse = function(string) { - try { - d3_date = d3_date_utc; - var date = local.parse(string); - return date && date._; - } finally { - d3_date = Date; - } - }; - - format.toString = local.toString; - - return format; -} diff --git a/src/time/format.js b/src/time/format.js deleted file mode 100644 index cb40f700b273ad..00000000000000 --- a/src/time/format.js +++ /dev/null @@ -1,321 +0,0 @@ -import "../arrays/map"; -import "../format/requote"; -import "day"; -import "format-localized"; -import "time"; -import "week"; - -d3_time.format = d3_time_format; - -function d3_time_format(template) { - var n = template.length; - - function format(date) { - var string = [], - i = -1, - j = 0, - c, - p, - f; - while (++i < n) { - if (template.charCodeAt(i) === 37) { - string.push(template.substring(j, i)); - if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); - if (f = d3_time_formats[c]) c = f(date, p == null ? (c === "e" ? " " : "0") : p); - string.push(c); - j = i + 1; - } - } - string.push(template.substring(j, i)); - return string.join(""); - } - - format.parse = function(string) { - var d = {y: 1900, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0, Z: null}, - i = d3_time_parse(d, template, string, 0); - if (i != string.length) return null; - - // The am-pm flag is 0 for AM, and 1 for PM. - if ("p" in d) d.H = d.H % 12 + d.p * 12; - - // If a time zone is specified, it is always relative to UTC; - // we need to use d3_date_utc if we aren’t already. - var localZ = d.Z != null && d3_date !== d3_date_utc, - date = new (localZ ? d3_date_utc : d3_date); - - // Set year, month, date. - if ("j" in d) date.setFullYear(d.y, 0, d.j); - else if ("w" in d && ("W" in d || "U" in d)) { - date.setFullYear(d.y, 0, 1); - date.setFullYear(d.y, 0, "W" in d - ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 - : d.w + d.U * 7 - (date.getDay() + 6) % 7); - } else date.setFullYear(d.y, d.m, d.d); - - // Set hours, minutes, seconds and milliseconds. - date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L); - - return localZ ? date._ : date; - }; - - format.toString = function() { - return template; - }; - - return format; -} - -function d3_time_parse(date, template, string, j) { - var c, - p, - t, - i = 0, - n = template.length, - m = string.length; - while (i < n) { - if (j >= m) return -1; - c = template.charCodeAt(i++); - if (c === 37) { - t = template.charAt(i++); - p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; - if (!p || ((j = p(date, string, j)) < 0)) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - return j; -} - -function d3_time_formatRe(names) { - return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); -} - -function d3_time_formatLookup(names) { - var map = new d3_Map, i = -1, n = names.length; - while (++i < n) map.set(names[i].toLowerCase(), i); - return map; -} - -function d3_time_formatPad(value, fill, width) { - var sign = value < 0 ? "-" : "", - string = (sign ? -value : value) + "", - length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); -} - -var d3_time_dayRe = d3_time_formatRe(d3_time_days), - d3_time_dayLookup = d3_time_formatLookup(d3_time_days), - d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations), - d3_time_dayAbbrevLookup = d3_time_formatLookup(d3_time_dayAbbreviations), - d3_time_monthRe = d3_time_formatRe(d3_time_months), - d3_time_monthLookup = d3_time_formatLookup(d3_time_months), - d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations), - d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations), - d3_time_percentRe = /^%/; - -var d3_time_formatPads = { - "-": "", - "_": " ", - "0": "0" -}; - -var d3_time_formats = { - a: function(d) { return d3_time_dayAbbreviations[d.getDay()]; }, - A: function(d) { return d3_time_days[d.getDay()]; }, - b: function(d) { return d3_time_monthAbbreviations[d.getMonth()]; }, - B: function(d) { return d3_time_months[d.getMonth()]; }, - c: d3_time_format(d3_time_formatDateTime), - d: function(d, p) { return d3_time_formatPad(d.getDate(), p, 2); }, - e: function(d, p) { return d3_time_formatPad(d.getDate(), p, 2); }, - H: function(d, p) { return d3_time_formatPad(d.getHours(), p, 2); }, - I: function(d, p) { return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); }, - j: function(d, p) { return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); }, - L: function(d, p) { return d3_time_formatPad(d.getMilliseconds(), p, 3); }, - m: function(d, p) { return d3_time_formatPad(d.getMonth() + 1, p, 2); }, - M: function(d, p) { return d3_time_formatPad(d.getMinutes(), p, 2); }, - p: function(d) { return d.getHours() >= 12 ? "PM" : "AM"; }, - S: function(d, p) { return d3_time_formatPad(d.getSeconds(), p, 2); }, - U: function(d, p) { return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); }, - w: function(d) { return d.getDay(); }, - W: function(d, p) { return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); }, - x: d3_time_format(d3_time_formatDate), - X: d3_time_format(d3_time_formatTime), - y: function(d, p) { return d3_time_formatPad(d.getFullYear() % 100, p, 2); }, - Y: function(d, p) { return d3_time_formatPad(d.getFullYear() % 10000, p, 4); }, - Z: d3_time_zone, - "%": function() { return "%"; } -}; - -var d3_time_parsers = { - a: d3_time_parseWeekdayAbbrev, - A: d3_time_parseWeekday, - b: d3_time_parseMonthAbbrev, - B: d3_time_parseMonth, - c: d3_time_parseLocaleFull, - d: d3_time_parseDay, - e: d3_time_parseDay, - H: d3_time_parseHour24, - I: d3_time_parseHour24, - j: d3_time_parseDayOfYear, - L: d3_time_parseMilliseconds, - m: d3_time_parseMonthNumber, - M: d3_time_parseMinutes, - p: d3_time_parseAmPm, - S: d3_time_parseSeconds, - U: d3_time_parseWeekNumberSunday, - w: d3_time_parseWeekdayNumber, - W: d3_time_parseWeekNumberMonday, - x: d3_time_parseLocaleDate, - X: d3_time_parseLocaleTime, - y: d3_time_parseYear, - Y: d3_time_parseFullYear, - Z: d3_time_parseZone, - "%": d3_time_parseLiteralPercent -}; - -function d3_time_parseWeekdayAbbrev(date, string, i) { - d3_time_dayAbbrevRe.lastIndex = 0; - var n = d3_time_dayAbbrevRe.exec(string.substring(i)); - return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; -} - -function d3_time_parseWeekday(date, string, i) { - d3_time_dayRe.lastIndex = 0; - var n = d3_time_dayRe.exec(string.substring(i)); - return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; -} - -function d3_time_parseWeekdayNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 1)); - return n ? (date.w = +n[0], i + n[0].length) : -1; -} - -function d3_time_parseWeekNumberSunday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i)); - return n ? (date.U = +n[0], i + n[0].length) : -1; -} - -function d3_time_parseWeekNumberMonday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i)); - return n ? (date.W = +n[0], i + n[0].length) : -1; -} - -function d3_time_parseMonthAbbrev(date, string, i) { - d3_time_monthAbbrevRe.lastIndex = 0; - var n = d3_time_monthAbbrevRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; -} - -function d3_time_parseMonth(date, string, i) { - d3_time_monthRe.lastIndex = 0; - var n = d3_time_monthRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; -} - -function d3_time_parseLocaleFull(date, string, i) { - return d3_time_parse(date, d3_time_formats.c.toString(), string, i); -} - -function d3_time_parseLocaleDate(date, string, i) { - return d3_time_parse(date, d3_time_formats.x.toString(), string, i); -} - -function d3_time_parseLocaleTime(date, string, i) { - return d3_time_parse(date, d3_time_formats.X.toString(), string, i); -} - -function d3_time_parseFullYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 4)); - return n ? (date.y = +n[0], i + n[0].length) : -1; -} - -function d3_time_parseYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; -} - -function d3_time_parseZone(date, string, i) { - return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) - ? (date.Z = +string, i + 5) - : -1; -} - -function d3_time_expandYear(d) { - return d + (d > 68 ? 1900 : 2000); -} - -function d3_time_parseMonthNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.m = n[0] - 1, i + n[0].length) : -1; -} - -function d3_time_parseDay(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.d = +n[0], i + n[0].length) : -1; -} - -function d3_time_parseDayOfYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.j = +n[0], i + n[0].length) : -1; -} - -// Note: we don't validate that the hour is in the range [0,23] or [1,12]. -function d3_time_parseHour24(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.H = +n[0], i + n[0].length) : -1; -} - -function d3_time_parseMinutes(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.M = +n[0], i + n[0].length) : -1; -} - -function d3_time_parseSeconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.S = +n[0], i + n[0].length) : -1; -} - -function d3_time_parseMilliseconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.L = +n[0], i + n[0].length) : -1; -} - -// Note: we don't look at the next directive. -var d3_time_numberRe = /^\s*\d+/; - -function d3_time_parseAmPm(date, string, i) { - var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase()); - return n == null ? -1 : (date.p = n, i); -} - -var d3_time_amPmLookup = d3.map({ - am: 0, - pm: 1 -}); - -// TODO table of time zone offset names? -function d3_time_zone(d) { - var z = d.getTimezoneOffset(), - zs = z > 0 ? "-" : "+", - zh = ~~(Math.abs(z) / 60), - zm = Math.abs(z) % 60; - return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); -} - -function d3_time_parseLiteralPercent(date, string, i) { - d3_time_percentRe.lastIndex = 0; - var n = d3_time_percentRe.exec(string.substring(i, i + 1)); - return n ? i + n[0].length : -1; -} diff --git a/src/time/hour.js b/src/time/hour.js deleted file mode 100644 index 0c6011d283e9d2..00000000000000 --- a/src/time/hour.js +++ /dev/null @@ -1,14 +0,0 @@ -import "interval"; -import "time"; - -d3_time.hour = d3_time_interval(function(date) { - var timezone = date.getTimezoneOffset() / 60; - return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); -}, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 36e5); // DST breaks setHours -}, function(date) { - return date.getHours(); -}); - -d3_time.hours = d3_time.hour.range; -d3_time.hours.utc = d3_time.hour.utc.range; diff --git a/src/time/index.js b/src/time/index.js deleted file mode 100644 index 91896f3e1d118f..00000000000000 --- a/src/time/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import "time"; -import "format-localized"; -import "format"; -import "format-utc"; -import "format-iso"; -import "interval"; -import "second"; -import "minute"; -import "hour"; -import "day"; -import "week"; -import "month"; -import "year"; -import "scale"; -import "scale-utc"; diff --git a/src/time/interval.js b/src/time/interval.js deleted file mode 100644 index b177b2001694db..00000000000000 --- a/src/time/interval.js +++ /dev/null @@ -1,71 +0,0 @@ -import "time"; - -function d3_time_interval(local, step, number) { - - function round(date) { - var d0 = local(date), d1 = offset(d0, 1); - return date - d0 < d1 - date ? d0 : d1; - } - - function ceil(date) { - step(date = local(new d3_date(date - 1)), 1); - return date; - } - - function offset(date, k) { - step(date = new d3_date(+date), k); - return date; - } - - function range(t0, t1, dt) { - var time = ceil(t0), times = []; - if (dt > 1) { - while (time < t1) { - if (!(number(time) % dt)) times.push(new Date(+time)); - step(time, 1); - } - } else { - while (time < t1) times.push(new Date(+time)), step(time, 1); - } - return times; - } - - function range_utc(t0, t1, dt) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = t0; - return range(utc, t1, dt); - } finally { - d3_date = Date; - } - } - - local.floor = local; - local.round = round; - local.ceil = ceil; - local.offset = offset; - local.range = range; - - var utc = local.utc = d3_time_interval_utc(local); - utc.floor = utc; - utc.round = d3_time_interval_utc(round); - utc.ceil = d3_time_interval_utc(ceil); - utc.offset = d3_time_interval_utc(offset); - utc.range = range_utc; - - return local; -} - -function d3_time_interval_utc(method) { - return function(date, k) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = date; - return method(utc, k)._; - } finally { - d3_date = Date; - } - }; -} diff --git a/src/time/minute.js b/src/time/minute.js deleted file mode 100644 index ad081f68c4e2cf..00000000000000 --- a/src/time/minute.js +++ /dev/null @@ -1,13 +0,0 @@ -import "interval"; -import "time"; - -d3_time.minute = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 6e4) * 6e4); -}, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 6e4); // DST breaks setMinutes -}, function(date) { - return date.getMinutes(); -}); - -d3_time.minutes = d3_time.minute.range; -d3_time.minutes.utc = d3_time.minute.utc.range; diff --git a/src/time/month.js b/src/time/month.js deleted file mode 100644 index 577d5b20f8a1b9..00000000000000 --- a/src/time/month.js +++ /dev/null @@ -1,16 +0,0 @@ -import "day"; -import "interval"; -import "time"; - -d3_time.month = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setDate(1); - return date; -}, function(date, offset) { - date.setMonth(date.getMonth() + offset); -}, function(date) { - return date.getMonth(); -}); - -d3_time.months = d3_time.month.range; -d3_time.months.utc = d3_time.month.utc.range; diff --git a/src/time/scale-utc.js b/src/time/scale-utc.js deleted file mode 100644 index 166f3055a78cfa..00000000000000 --- a/src/time/scale-utc.js +++ /dev/null @@ -1,28 +0,0 @@ -import "../core/true"; -import "../scale/linear"; -import "format"; -import "format-utc"; -import "scale"; - -var d3_time_scaleUTCMethods = d3_time_scaleLocalMethods.map(function(m) { - return [m[0].utc, m[1]]; -}); - -var d3_time_scaleUTCFormats = [ - [d3_time_formatUtc("%Y"), d3_true], - [d3_time_formatUtc("%B"), function(d) { return d.getUTCMonth(); }], - [d3_time_formatUtc("%b %d"), function(d) { return d.getUTCDate() != 1; }], - [d3_time_formatUtc("%a %d"), function(d) { return d.getUTCDay() && d.getUTCDate() != 1; }], - [d3_time_formatUtc("%I %p"), function(d) { return d.getUTCHours(); }], - [d3_time_formatUtc("%I:%M"), function(d) { return d.getUTCMinutes(); }], - [d3_time_formatUtc(":%S"), function(d) { return d.getUTCSeconds(); }], - [d3_time_formatUtc(".%L"), function(d) { return d.getUTCMilliseconds(); }] -]; - -var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats); - -d3_time_scaleUTCMethods.year = d3_time.year.utc; - -d3_time.scale.utc = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat); -}; diff --git a/src/time/scale.js b/src/time/scale.js deleted file mode 100644 index ac4520ebaa3401..00000000000000 --- a/src/time/scale.js +++ /dev/null @@ -1,165 +0,0 @@ -import "../arrays/bisect"; -import "../arrays/range"; -import "../core/rebind"; -import "../core/true"; -import "../scale/linear"; -import "../scale/nice"; -import "day"; -import "format"; -import "hour"; -import "minute"; -import "month"; -import "second"; -import "time"; -import "week"; -import "year"; - -function d3_time_scale(linear, methods, format) { - - function scale(x) { - return linear(x); - } - - scale.invert = function(x) { - return d3_time_scaleDate(linear.invert(x)); - }; - - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(d3_time_scaleDate); - linear.domain(x); - return scale; - }; - - function tickMethod(extent, count) { - var span = extent[1] - extent[0], - target = span / count, - i = d3.bisect(d3_time_scaleSteps, target); - return i == d3_time_scaleSteps.length ? [methods.year, d3_scale_linearTickRange(extent.map(function(d) { return d / 31536e6; }), count)[2]] - : !i ? [d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2]] - : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; - } - - scale.nice = function(interval, skip) { - var domain = scale.domain(), - extent = d3_scaleExtent(domain), - method = interval == null ? tickMethod(extent, 10) - : typeof interval === "number" && tickMethod(extent, interval); - - if (method) interval = method[0], skip = method[1]; - - function skipped(date) { - return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; - } - - return scale.domain(d3_scale_nice(domain, skip > 1 ? { - floor: function(date) { - while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); - return date; - }, - ceil: function(date) { - while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); - return date; - } - } : interval)); - }; - - scale.ticks = function(interval, skip) { - var extent = d3_scaleExtent(scale.domain()), - method = interval == null ? tickMethod(extent, 10) - : typeof interval === "number" ? tickMethod(extent, interval) - : !interval.range && [{range: interval}, skip]; // assume deprecated range function - - if (method) interval = method[0], skip = method[1]; - - return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); // inclusive upper bound - }; - - scale.tickFormat = function() { - return format; - }; - - scale.copy = function() { - return d3_time_scale(linear.copy(), methods, format); - }; - - return d3_scale_linearRebind(scale, linear); -} - -function d3_time_scaleDate(t) { - return new Date(t); -} - -function d3_time_scaleFormat(formats) { - return function(date) { - var i = formats.length - 1, f = formats[i]; - while (!f[1](date)) f = formats[--i]; - return f[0](date); - }; -} - -var d3_time_scaleSteps = [ - 1e3, // 1-second - 5e3, // 5-second - 15e3, // 15-second - 3e4, // 30-second - 6e4, // 1-minute - 3e5, // 5-minute - 9e5, // 15-minute - 18e5, // 30-minute - 36e5, // 1-hour - 108e5, // 3-hour - 216e5, // 6-hour - 432e5, // 12-hour - 864e5, // 1-day - 1728e5, // 2-day - 6048e5, // 1-week - 2592e6, // 1-month - 7776e6, // 3-month - 31536e6 // 1-year -]; - -var d3_time_scaleLocalMethods = [ - [d3_time.second, 1], - [d3_time.second, 5], - [d3_time.second, 15], - [d3_time.second, 30], - [d3_time.minute, 1], - [d3_time.minute, 5], - [d3_time.minute, 15], - [d3_time.minute, 30], - [d3_time.hour, 1], - [d3_time.hour, 3], - [d3_time.hour, 6], - [d3_time.hour, 12], - [d3_time.day, 1], - [d3_time.day, 2], - [d3_time.week, 1], - [d3_time.month, 1], - [d3_time.month, 3], - [d3_time.year, 1] -]; - -var d3_time_scaleLocalFormats = [ - [d3_time_format("%Y"), d3_true], - [d3_time_format("%B"), function(d) { return d.getMonth(); }], - [d3_time_format("%b %d"), function(d) { return d.getDate() != 1; }], - [d3_time_format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }], - [d3_time_format("%I %p"), function(d) { return d.getHours(); }], - [d3_time_format("%I:%M"), function(d) { return d.getMinutes(); }], - [d3_time_format(":%S"), function(d) { return d.getSeconds(); }], - [d3_time_format(".%L"), function(d) { return d.getMilliseconds(); }] -]; - -var d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); - -d3_time_scaleLocalMethods.year = d3_time.year; - -d3_time.scale = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); -}; - -var d3_time_scaleMilliseconds = { - range: function(start, stop, step) { - return d3.range(+start, +stop, step).map(d3_time_scaleDate); - } -}; diff --git a/src/time/second.js b/src/time/second.js deleted file mode 100644 index 745c4b91171e61..00000000000000 --- a/src/time/second.js +++ /dev/null @@ -1,13 +0,0 @@ -import "interval"; -import "time"; - -d3_time.second = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 1e3) * 1e3); -}, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 1e3); // DST breaks setSeconds -}, function(date) { - return date.getSeconds(); -}); - -d3_time.seconds = d3_time.second.range; -d3_time.seconds.utc = d3_time.second.utc.range; diff --git a/src/time/time.js b/src/time/time.js deleted file mode 100644 index ef55f55d9c71e7..00000000000000 --- a/src/time/time.js +++ /dev/null @@ -1,34 +0,0 @@ -var d3_time = d3.time = {}, - d3_date = Date, - d3_time_daySymbols = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; - -function d3_date_utc() { - this._ = new Date(arguments.length > 1 - ? Date.UTC.apply(this, arguments) - : arguments[0]); -} - -d3_date_utc.prototype = { - getDate: function() { return this._.getUTCDate(); }, - getDay: function() { return this._.getUTCDay(); }, - getFullYear: function() { return this._.getUTCFullYear(); }, - getHours: function() { return this._.getUTCHours(); }, - getMilliseconds: function() { return this._.getUTCMilliseconds(); }, - getMinutes: function() { return this._.getUTCMinutes(); }, - getMonth: function() { return this._.getUTCMonth(); }, - getSeconds: function() { return this._.getUTCSeconds(); }, - getTime: function() { return this._.getTime(); }, - getTimezoneOffset: function() { return 0; }, - valueOf: function() { return this._.valueOf(); }, - setDate: function() { d3_time_prototype.setUTCDate.apply(this._, arguments); }, - setDay: function() { d3_time_prototype.setUTCDay.apply(this._, arguments); }, - setFullYear: function() { d3_time_prototype.setUTCFullYear.apply(this._, arguments); }, - setHours: function() { d3_time_prototype.setUTCHours.apply(this._, arguments); }, - setMilliseconds: function() { d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); }, - setMinutes: function() { d3_time_prototype.setUTCMinutes.apply(this._, arguments); }, - setMonth: function() { d3_time_prototype.setUTCMonth.apply(this._, arguments); }, - setSeconds: function() { d3_time_prototype.setUTCSeconds.apply(this._, arguments); }, - setTime: function() { d3_time_prototype.setTime.apply(this._, arguments); } -}; - -var d3_time_prototype = Date.prototype; diff --git a/src/time/week.js b/src/time/week.js deleted file mode 100644 index 205cb0955a448a..00000000000000 --- a/src/time/week.js +++ /dev/null @@ -1,32 +0,0 @@ -import "day"; -import "interval"; -import "time"; -import "year"; - -d3_time_daySymbols.forEach(function(day, i) { - day = day.toLowerCase(); - i = 7 - i; - - var interval = d3_time[day] = d3_time_interval(function(date) { - (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); - return date; - }, function(date, offset) { - date.setDate(date.getDate() + Math.floor(offset) * 7); - }, function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); - }); - - d3_time[day + "s"] = interval.range; - d3_time[day + "s"].utc = interval.utc.range; - - d3_time[day + "OfYear"] = function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); - }; -}); - -d3_time.week = d3_time.sunday; -d3_time.weeks = d3_time.sunday.range; -d3_time.weeks.utc = d3_time.sunday.utc.range; -d3_time.weekOfYear = d3_time.sundayOfYear; diff --git a/src/time/year.js b/src/time/year.js deleted file mode 100644 index 3ac02a2568c11c..00000000000000 --- a/src/time/year.js +++ /dev/null @@ -1,16 +0,0 @@ -import "day"; -import "interval"; -import "time"; - -d3_time.year = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setMonth(0, 1); - return date; -}, function(date, offset) { - date.setFullYear(date.getFullYear() + offset); -}, function(date) { - return date.getFullYear(); -}); - -d3_time.years = d3_time.year.range; -d3_time.years.utc = d3_time.year.utc.range; diff --git a/src/transition/attr.js b/src/transition/attr.js deleted file mode 100644 index 31c77f1465a9bc..00000000000000 --- a/src/transition/attr.js +++ /dev/null @@ -1,58 +0,0 @@ -import "../core/ns"; -import "../interpolate/interpolate"; -import "../interpolate/transform"; -import "transition"; -import "tween"; - -d3_transitionPrototype.attr = function(nameNS, value) { - if (arguments.length < 2) { - - // For attr(object), the object specifies the names and values of the - // attributes to transition. The values may be functions that are - // evaluated for each element. - for (value in nameNS) this.attr(value, nameNS[value]); - return this; - } - - var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, - name = d3.ns.qualify(nameNS); - - // For attr(string, null), remove the attribute with the specified name. - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - - // For attr(string, string), set the attribute with the specified name. - function attrTween(b) { - return b == null ? attrNull : (b += "", function() { - var a = this.getAttribute(name), i; - return a !== b && (i = interpolate(a, b), function(t) { this.setAttribute(name, i(t)); }); - }); - } - function attrTweenNS(b) { - return b == null ? attrNullNS : (b += "", function() { - var a = this.getAttributeNS(name.space, name.local), i; - return a !== b && (i = interpolate(a, b), function(t) { this.setAttributeNS(name.space, name.local, i(t)); }); - }); - } - - return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); -}; - -d3_transitionPrototype.attrTween = function(nameNS, tween) { - var name = d3.ns.qualify(nameNS); - - function attrTween(d, i) { - var f = tween.call(this, d, i, this.getAttribute(name)); - return f && function(t) { this.setAttribute(name, f(t)); }; - } - function attrTweenNS(d, i) { - var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); - return f && function(t) { this.setAttributeNS(name.space, name.local, f(t)); }; - } - - return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); -}; diff --git a/src/transition/delay.js b/src/transition/delay.js deleted file mode 100644 index 8f12707a06637c..00000000000000 --- a/src/transition/delay.js +++ /dev/null @@ -1,9 +0,0 @@ -import "../selection/each"; -import "transition"; - -d3_transitionPrototype.delay = function(value) { - var id = this.id; - return d3_selection_each(this, typeof value === "function" - ? function(node, i, j) { node.__transition__[id].delay = +value.call(node, node.__data__, i, j); } - : (value = +value, function(node) { node.__transition__[id].delay = value; })); -}; diff --git a/src/transition/duration.js b/src/transition/duration.js deleted file mode 100644 index dd45c372309890..00000000000000 --- a/src/transition/duration.js +++ /dev/null @@ -1,9 +0,0 @@ -import "../selection/each"; -import "transition"; - -d3_transitionPrototype.duration = function(value) { - var id = this.id; - return d3_selection_each(this, typeof value === "function" - ? function(node, i, j) { node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j)); } - : (value = Math.max(1, value), function(node) { node.__transition__[id].duration = value; })); -}; diff --git a/src/transition/each.js b/src/transition/each.js deleted file mode 100644 index 81e53bab09ded0..00000000000000 --- a/src/transition/each.js +++ /dev/null @@ -1,23 +0,0 @@ -import "../selection/each"; -import "transition"; - -d3_transitionPrototype.each = function(type, listener) { - var id = this.id; - if (arguments.length < 2) { - var inherit = d3_transitionInherit, - inheritId = d3_transitionInheritId; - d3_transitionInheritId = id; - d3_selection_each(this, function(node, i, j) { - d3_transitionInherit = node.__transition__[id]; - type.call(node, node.__data__, i, j); - }); - d3_transitionInherit = inherit; - d3_transitionInheritId = inheritId; - } else { - d3_selection_each(this, function(node) { - var transition = node.__transition__[id]; - (transition.event || (transition.event = d3.dispatch("start", "end"))).on(type, listener); - }); - } - return this; -}; diff --git a/src/transition/ease.js b/src/transition/ease.js deleted file mode 100644 index b13b9df149a60a..00000000000000 --- a/src/transition/ease.js +++ /dev/null @@ -1,10 +0,0 @@ -import "../interpolate/ease"; -import "../selection/each"; -import "transition"; - -d3_transitionPrototype.ease = function(value) { - var id = this.id; - if (arguments.length < 1) return this.node().__transition__[id].ease; - if (typeof value !== "function") value = d3.ease.apply(d3, arguments); - return d3_selection_each(this, function(node) { node.__transition__[id].ease = value; }); -}; diff --git a/src/transition/filter.js b/src/transition/filter.js deleted file mode 100644 index eee210e7f13b7c..00000000000000 --- a/src/transition/filter.js +++ /dev/null @@ -1,22 +0,0 @@ -import "../selection/filter"; -import "transition"; - -d3_transitionPrototype.filter = function(filter) { - var subgroups = [], - subgroup, - group, - node; - - if (typeof filter !== "function") filter = d3_selection_filter(filter); - - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i)) { - subgroup.push(node); - } - } - } - - return d3_transition(subgroups, this.id); -}; diff --git a/src/transition/index.js b/src/transition/index.js deleted file mode 100644 index c2a6702ff1f692..00000000000000 --- a/src/transition/index.js +++ /dev/null @@ -1 +0,0 @@ -import "transition"; diff --git a/src/transition/remove.js b/src/transition/remove.js deleted file mode 100644 index 3887db4e41f76e..00000000000000 --- a/src/transition/remove.js +++ /dev/null @@ -1,8 +0,0 @@ -import "transition"; - -d3_transitionPrototype.remove = function() { - return this.each("end.transition", function() { - var p; - if (this.__transition__.count < 2 && (p = this.parentNode)) p.removeChild(this); - }); -}; diff --git a/src/transition/select.js b/src/transition/select.js deleted file mode 100644 index 01ef61139c09e7..00000000000000 --- a/src/transition/select.js +++ /dev/null @@ -1,27 +0,0 @@ -import "../selection/select"; -import "transition"; - -d3_transitionPrototype.select = function(selector) { - var id = this.id, - subgroups = [], - subgroup, - subnode, - node; - - selector = d3_selection_selector(selector); - - for (var j = -1, m = this.length; ++j < m;) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n;) { - if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - d3_transitionNode(subnode, i, id, node.__transition__[id]); - subgroup.push(subnode); - } else { - subgroup.push(null); - } - } - } - - return d3_transition(subgroups, id); -}; diff --git a/src/transition/selectAll.js b/src/transition/selectAll.js deleted file mode 100644 index 0133fec8184fb4..00000000000000 --- a/src/transition/selectAll.js +++ /dev/null @@ -1,30 +0,0 @@ -import "../selection/select"; -import "transition"; - -d3_transitionPrototype.selectAll = function(selector) { - var id = this.id, - subgroups = [], - subgroup, - subnodes, - node, - subnode, - transition; - - selector = d3_selection_selectorAll(selector); - - for (var j = -1, m = this.length; ++j < m;) { - for (var group = this[j], i = -1, n = group.length; ++i < n;) { - if (node = group[i]) { - transition = node.__transition__[id]; - subnodes = selector.call(node, node.__data__, i, j); - subgroups.push(subgroup = []); - for (var k = -1, o = subnodes.length; ++k < o;) { - if (subnode = subnodes[k]) d3_transitionNode(subnode, k, id, transition); - subgroup.push(subnode); - } - } - } - } - - return d3_transition(subgroups, id); -}; diff --git a/src/transition/style.js b/src/transition/style.js deleted file mode 100644 index e402c127735a6f..00000000000000 --- a/src/transition/style.js +++ /dev/null @@ -1,53 +0,0 @@ -import "../core/document"; -import "../interpolate/interpolate"; -import "transition"; -import "tween"; - -d3_transitionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - - // For style(object) or style(object, string), the object specifies the - // names and values of the attributes to set or remove. The values may be - // functions that are evaluated for each element. The optional string - // specifies the priority. - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.style(priority, name[priority], value); - return this; - } - - // For style(string, string) or style(string, function), use the default - // priority. The priority is ignored for style(string, null). - priority = ""; - } - - // For style(name, null) or style(name, null, priority), remove the style - // property with the specified name. The priority is ignored. - function styleNull() { - this.style.removeProperty(name); - } - - // For style(name, string) or style(name, string, priority), set the style - // property with the specified name, using the specified priority. - // Otherwise, a name, value and priority are specified, and handled as below. - function styleString(b) { - return b == null ? styleNull : (b += "", function() { - var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; - return a !== b && (i = d3_interpolate(a, b), function(t) { this.style.setProperty(name, i(t), priority); }); - }); - } - - return d3_transition_tween(this, "style." + name, value, styleString); -}; - -d3_transitionPrototype.styleTween = function(name, tween, priority) { - if (arguments.length < 3) priority = ""; - - function styleTween(d, i) { - var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); - return f && function(t) { this.style.setProperty(name, f(t), priority); }; - } - - return this.tween("style." + name, styleTween); -}; diff --git a/src/transition/subtransition.js b/src/transition/subtransition.js deleted file mode 100644 index 9c782bf3dd3c94..00000000000000 --- a/src/transition/subtransition.js +++ /dev/null @@ -1,25 +0,0 @@ -import "transition"; - -d3_transitionPrototype.transition = function() { - var id0 = this.id, - id1 = ++d3_transitionId, - subgroups = [], - subgroup, - group, - node, - transition; - - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if (node = group[i]) { - transition = Object.create(node.__transition__[id0]); - transition.delay += transition.duration; - d3_transitionNode(node, i, id1, transition); - } - subgroup.push(node); - } - } - - return d3_transition(subgroups, id1); -}; diff --git a/src/transition/text.js b/src/transition/text.js deleted file mode 100644 index 0e2455a27db944..00000000000000 --- a/src/transition/text.js +++ /dev/null @@ -1,11 +0,0 @@ -import "transition"; -import "tween"; - -d3_transitionPrototype.text = function(value) { - return d3_transition_tween(this, "text", value, d3_transition_text); -}; - -function d3_transition_text(b) { - if (b == null) b = ""; - return function() { this.textContent = b; }; -} diff --git a/src/transition/transition.js b/src/transition/transition.js deleted file mode 100644 index 40f7fcfc5bdd4d..00000000000000 --- a/src/transition/transition.js +++ /dev/null @@ -1,114 +0,0 @@ -import "../arrays/map"; -import "../core/subclass"; -import "../event/dispatch"; -import "../event/timer"; -import "../interpolate/ease"; -import "../selection/selection"; - -function d3_transition(groups, id) { - d3_subclass(groups, d3_transitionPrototype); - - groups.id = id; // Note: read-only! - - return groups; -} - -var d3_transitionPrototype = [], - d3_transitionId = 0, - d3_transitionInheritId, - d3_transitionInherit; - -d3_transitionPrototype.call = d3_selectionPrototype.call; -d3_transitionPrototype.empty = d3_selectionPrototype.empty; -d3_transitionPrototype.node = d3_selectionPrototype.node; -d3_transitionPrototype.size = d3_selectionPrototype.size; - -d3.transition = function(selection) { - return arguments.length - ? (d3_transitionInheritId ? selection.transition() : selection) - : d3_selectionRoot.transition(); -}; - -d3.transition.prototype = d3_transitionPrototype; - -import "select"; -import "selectAll"; -import "filter"; -import "attr"; -import "style"; -import "text"; -import "remove"; -import "ease"; -import "delay"; -import "duration"; -import "each"; -import "subtransition"; -import "tween"; - -function d3_transitionNode(node, i, id, inherit) { - var lock = node.__transition__ || (node.__transition__ = {active: 0, count: 0}), - transition = lock[id]; - - if (!transition) { - var time = inherit.time; - - transition = lock[id] = { - tween: new d3_Map, - time: time, - ease: inherit.ease, - delay: inherit.delay, - duration: inherit.duration - }; - - ++lock.count; - - d3.timer(function(elapsed) { - var d = node.__data__, - ease = transition.ease, - delay = transition.delay, - duration = transition.duration, - tweened = []; - - if (delay <= elapsed) return start(elapsed); - d3_timer_replace(start, delay, time); - - function start(elapsed) { - if (lock.active > id) return stop(); - lock.active = id; - transition.event && transition.event.start.call(node, d, i); - - transition.tween.forEach(function(key, value) { - if (value = value.call(node, d, i)) { - tweened.push(value); - } - }); - - if (tick(elapsed)) return 1; - d3_timer_replace(tick, 0, time); - } - - function tick(elapsed) { - if (lock.active !== id) return stop(); - - var t = (elapsed - delay) / duration, - e = ease(t), - n = tweened.length; - - while (n > 0) { - tweened[--n].call(node, e); - } - - if (t >= 1) { - transition.event && transition.event.end.call(node, d, i); - return stop(); - } - } - - function stop() { - if (--lock.count) delete lock[id]; - else delete node.__transition__; - return 1; - } - }, 0, time); - } -} diff --git a/src/transition/tween.js b/src/transition/tween.js deleted file mode 100644 index 405ada28cd3a76..00000000000000 --- a/src/transition/tween.js +++ /dev/null @@ -1,17 +0,0 @@ -import "../selection/each"; -import "transition"; - -d3_transitionPrototype.tween = function(name, tween) { - var id = this.id; - if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); - return d3_selection_each(this, tween == null - ? function(node) { node.__transition__[id].tween.remove(name); } - : function(node) { node.__transition__[id].tween.set(name, tween); }); -}; - -function d3_transition_tween(groups, name, value, tween) { - var id = groups.id; - return d3_selection_each(groups, typeof value === "function" - ? function(node, i, j) { node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); } - : (value = tween(value), function(node) { node.__transition__[id].tween.set(name, value); })); -} diff --git a/src/xhr/html.js b/src/xhr/html.js deleted file mode 100644 index d42283b9fe9835..00000000000000 --- a/src/xhr/html.js +++ /dev/null @@ -1,12 +0,0 @@ -import "../core/document"; -import "xhr"; - -d3.html = function(url, callback) { - return d3_xhr(url, "text/html", d3_html, callback); -}; - -function d3_html(request) { - var range = d3_document.createRange(); - range.selectNode(d3_document.body); - return range.createContextualFragment(request.responseText); -} diff --git a/src/xhr/index.js b/src/xhr/index.js deleted file mode 100644 index c71b4666a2c88e..00000000000000 --- a/src/xhr/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import "xhr"; -import "text"; -import "json"; -import "html"; -import "xml"; diff --git a/src/xhr/json.js b/src/xhr/json.js deleted file mode 100644 index f51bc2c047948e..00000000000000 --- a/src/xhr/json.js +++ /dev/null @@ -1,9 +0,0 @@ -import "xhr"; - -d3.json = function(url, callback) { - return d3_xhr(url, "application/json", d3_json, callback); -}; - -function d3_json(request) { - return JSON.parse(request.responseText); -} diff --git a/src/xhr/text.js b/src/xhr/text.js deleted file mode 100644 index 1f51e3dca2fba1..00000000000000 --- a/src/xhr/text.js +++ /dev/null @@ -1,5 +0,0 @@ -import "xhr"; - -d3.text = d3_xhrType(function(request) { - return request.responseText; -}); diff --git a/src/xhr/xhr.js b/src/xhr/xhr.js deleted file mode 100644 index bfbaf30e9687c0..00000000000000 --- a/src/xhr/xhr.js +++ /dev/null @@ -1,119 +0,0 @@ -import "../core/array"; -import "../core/document"; -import "../core/identity"; -import "../core/rebind"; -import "../event/dispatch"; - -d3.xhr = d3_xhrType(d3_identity); - -function d3_xhrType(response) { - return function(url, mimeType, callback) { - if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, mimeType = null; - return d3_xhr(url, mimeType, response, callback); - }; -} - -function d3_xhr(url, mimeType, response, callback) { - var xhr = {}, - dispatch = d3.dispatch("beforesend", "progress", "load", "error"), - headers = {}, - request = new XMLHttpRequest, - responseType = null; - - // If IE does not support CORS, use XDomainRequest. - if (d3_window.XDomainRequest - && !("withCredentials" in request) - && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest; - - "onload" in request - ? request.onload = request.onerror = respond - : request.onreadystatechange = function() { request.readyState > 3 && respond(); }; - - function respond() { - var status = request.status, result; - if (!status && request.responseText || status >= 200 && status < 300 || status === 304) { - try { - result = response.call(xhr, request); - } catch (e) { - dispatch.error.call(xhr, e); - return; - } - dispatch.load.call(xhr, result); - } else { - dispatch.error.call(xhr, request); - } - } - - request.onprogress = function(event) { - var o = d3.event; - d3.event = event; - try { dispatch.progress.call(xhr, request); } - finally { d3.event = o; } - }; - - xhr.header = function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers[name]; - if (value == null) delete headers[name]; - else headers[name] = value + ""; - return xhr; - }; - - // If mimeType is non-null and no Accept header is set, a default is used. - xhr.mimeType = function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return xhr; - }; - - // Specifies what type the response value should take; - // for instance, arraybuffer, blob, document, or text. - xhr.responseType = function(value) { - if (!arguments.length) return responseType; - responseType = value; - return xhr; - }; - - // Specify how to convert the response content to a specific type; - // changes the callback value on "load" events. - xhr.response = function(value) { - response = value; - return xhr; - }; - - // Convenience methods. - ["get", "post"].forEach(function(method) { - xhr[method] = function() { - return xhr.send.apply(xhr, [method].concat(d3_array(arguments))); - }; - }); - - // If callback is non-null, it will be used for error and load events. - xhr.send = function(method, data, callback) { - if (arguments.length === 2 && typeof data === "function") callback = data, data = null; - request.open(method, url, true); - if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; - if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); - if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); - if (responseType != null) request.responseType = responseType; - if (callback != null) xhr.on("error", callback).on("load", function(request) { callback(null, request); }); - dispatch.beforesend.call(xhr, request); - request.send(data == null ? null : data); - return xhr; - }; - - xhr.abort = function() { - request.abort(); - return xhr; - }; - - d3.rebind(xhr, dispatch, "on"); - - return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); -}; - -function d3_xhr_fixCallback(callback) { - return callback.length === 1 - ? function(error, request) { callback(error == null ? request : null); } - : callback; -} diff --git a/src/xhr/xml.js b/src/xhr/xml.js deleted file mode 100644 index 09c18e21702a92..00000000000000 --- a/src/xhr/xml.js +++ /dev/null @@ -1,5 +0,0 @@ -import "xhr"; - -d3.xml = d3_xhrType(function(request) { - return request.responseXML; -}); diff --git a/test/XMLHttpRequest.js b/test/XMLHttpRequest.js deleted file mode 100644 index 21ee57468e5e99..00000000000000 --- a/test/XMLHttpRequest.js +++ /dev/null @@ -1,60 +0,0 @@ -var fs = require("fs"); - -global.XMLHttpRequest = function XMLHttpRequest() { - var self = this, - info = self._info = {}, - headers = {}, - url; - - // TODO handle file system errors? - -self.readyState = 0; - - self.open = function(m, u, a) { - info.url = u; - info.async = a; - self.readyState = 1; - self.send = a ? read : readSync; - }; - - self.setRequestHeader = function(n, v) { - if (/^Accept$/i.test(n)) info.mimeType = v.split(/,/g)[0]; - }; - - function read() { - self.readyState = 2; - fs.readFile(info.url, "binary", function(e, d) { - if (e) { - self.status = 404; // assumed - } else { - self.status = 200; - self.responseText = d; - self.responseXML = {_xml: d}; - headers["Content-Length"] = d.length; - } - self.readyState = 4; - XMLHttpRequest._last = self; - if (self.onreadystatechange) self.onreadystatechange(); - }); - } - - function readSync() { - self.readyState = 2; - try { - var d = fs.readFileSync(info.url, "binary"); - self.status = 200; - self.responseText = d; - self.responseXML = {_xml: d}; - headers["Content-Length"] = d.length; - } catch (e) { - self.status = 404; // assumed - } - self.readyState = 4; - XMLHttpRequest._last = self; - if (self.onreadystatechange) self.onreadystatechange(); - } - - self.getResponseHeader = function(n) { - return headers[n]; - }; -}; diff --git a/test/arrays/ascending-test.js b/test/arrays/ascending-test.js deleted file mode 100644 index b7d9a7cf10fc25..00000000000000 --- a/test/arrays/ascending-test.js +++ /dev/null @@ -1,45 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.ascending"); - -suite.addBatch({ - "d3.ascending": { - topic: load("arrays/ascending").expression("d3.ascending"), - "numbers": { - "returns a negative number if a < b": function(ascending) { - assert.isTrue(ascending(0, 1) < 0); - }, - "returns a positive number if a > b": function(ascending) { - assert.isTrue(ascending(1, 0) > 0); - }, - "returns zero if a == b": function(ascending) { - assert.equal(ascending(0, 0), 0); - }, - "returns NaN if a or b is undefined": function(ascending) { - assert.isNaN(ascending(0, undefined)); - assert.isNaN(ascending(undefined, 0)); - assert.isNaN(ascending(undefined, undefined)); - }, - "returns NaN if a or b is NaN": function(ascending) { - assert.isNaN(ascending(0, NaN)); - assert.isNaN(ascending(NaN, 0)); - assert.isNaN(ascending(NaN, NaN)); - } - }, - "strings": { - "returns a negative number if a < b": function(ascending) { - assert.isTrue(ascending("a", "b") < 0); - }, - "returns a positive number if a > b": function(ascending) { - assert.isTrue(ascending("b", "a") > 0); - }, - "returns zero if a == b": function(ascending) { - assert.equal(ascending("a", "a"), 0); - } - } - } -}); - -suite.export(module); diff --git a/test/arrays/bisect-test.js b/test/arrays/bisect-test.js deleted file mode 100644 index 3a5b039211f1e4..00000000000000 --- a/test/arrays/bisect-test.js +++ /dev/null @@ -1,257 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.bisect"); - -var i30 = 1 << 30; - -suite.addBatch({ - "bisectLeft": { - topic: load("arrays/bisect").expression("d3.bisectLeft"), - "finds the index of an exact match": function(bisect) { - var array = [1, 2, 3]; - assert.equal(bisect(array, 1), 0); - assert.equal(bisect(array, 2), 1); - assert.equal(bisect(array, 3), 2); - }, - "finds the index of the first match": function(bisect) { - var array = [1, 2, 2, 3]; - assert.equal(bisect(array, 1), 0); - assert.equal(bisect(array, 2), 1); - assert.equal(bisect(array, 3), 3); - }, - "finds the insertion point of a non-exact match": function(bisect) { - var array = [1, 2, 3]; - assert.equal(bisect(array, 0.5), 0); - assert.equal(bisect(array, 1.5), 1); - assert.equal(bisect(array, 2.5), 2); - assert.equal(bisect(array, 3.5), 3); - }, - "has undefined behavior if the search value is unorderable": function(bisect) { - var array = [1, 2, 3]; - bisect(array, new Date(NaN)); // who knows what this will return! - bisect(array, undefined); - bisect(array, NaN); - }, - "observes the optional lower bound": function(bisect) { - var array = [1, 2, 3, 4, 5]; - assert.equal(bisect(array, 0, 2), 2); - assert.equal(bisect(array, 1, 2), 2); - assert.equal(bisect(array, 2, 2), 2); - assert.equal(bisect(array, 3, 2), 2); - assert.equal(bisect(array, 4, 2), 3); - assert.equal(bisect(array, 5, 2), 4); - assert.equal(bisect(array, 6, 2), 5); - }, - "observes the optional bounds": function(bisect) { - var array = [1, 2, 3, 4, 5]; - assert.equal(bisect(array, 0, 2, 3), 2); - assert.equal(bisect(array, 1, 2, 3), 2); - assert.equal(bisect(array, 2, 2, 3), 2); - assert.equal(bisect(array, 3, 2, 3), 2); - assert.equal(bisect(array, 4, 2, 3), 3); - assert.equal(bisect(array, 5, 2, 3), 3); - assert.equal(bisect(array, 6, 2, 3), 3); - }, - "large arrays": function(bisect) { - var array = [], - i = i30; - array[i++] = 1; - array[i++] = 2; - array[i++] = 3; - array[i++] = 4; - array[i++] = 5; - assert.equal(bisect(array, 0, i - 5, i), i - 5); - assert.equal(bisect(array, 1, i - 5, i), i - 5); - assert.equal(bisect(array, 2, i - 5, i), i - 4); - assert.equal(bisect(array, 3, i - 5, i), i - 3); - assert.equal(bisect(array, 4, i - 5, i), i - 2); - assert.equal(bisect(array, 5, i - 5, i), i - 1); - assert.equal(bisect(array, 6, i - 5, i), i - 0); - } - }, - "bisectRight": { - topic: load("arrays/bisect").expression("d3.bisectRight"), - "finds the index after an exact match": function(bisect) { - var array = [1, 2, 3]; - assert.equal(bisect(array, 1), 1); - assert.equal(bisect(array, 2), 2); - assert.equal(bisect(array, 3), 3); - }, - "finds the index after the last match": function(bisect) { - var array = [1, 2, 2, 3]; - assert.equal(bisect(array, 1), 1); - assert.equal(bisect(array, 2), 3); - assert.equal(bisect(array, 3), 4); - }, - "finds the insertion point of a non-exact match": function(bisect) { - var array = [1, 2, 3]; - assert.equal(bisect(array, 0.5), 0); - assert.equal(bisect(array, 1.5), 1); - assert.equal(bisect(array, 2.5), 2); - assert.equal(bisect(array, 3.5), 3); - }, - "observes the optional lower bound": function(bisect) { - var array = [1, 2, 3, 4, 5]; - assert.equal(bisect(array, 0, 2), 2); - assert.equal(bisect(array, 1, 2), 2); - assert.equal(bisect(array, 2, 2), 2); - assert.equal(bisect(array, 3, 2), 3); - assert.equal(bisect(array, 4, 2), 4); - assert.equal(bisect(array, 5, 2), 5); - assert.equal(bisect(array, 6, 2), 5); - }, - "observes the optional bounds": function(bisect) { - var array = [1, 2, 3, 4, 5]; - assert.equal(bisect(array, 0, 2, 3), 2); - assert.equal(bisect(array, 1, 2, 3), 2); - assert.equal(bisect(array, 2, 2, 3), 2); - assert.equal(bisect(array, 3, 2, 3), 3); - assert.equal(bisect(array, 4, 2, 3), 3); - assert.equal(bisect(array, 5, 2, 3), 3); - assert.equal(bisect(array, 6, 2, 3), 3); - }, - "large arrays": function(bisect) { - var array = [], - i = i30; - array[i++] = 1; - array[i++] = 2; - array[i++] = 3; - array[i++] = 4; - array[i++] = 5; - assert.equal(bisect(array, 0, i - 5, i), i - 5); - assert.equal(bisect(array, 1, i - 5, i), i - 4); - assert.equal(bisect(array, 2, i - 5, i), i - 3); - assert.equal(bisect(array, 3, i - 5, i), i - 2); - assert.equal(bisect(array, 4, i - 5, i), i - 1); - assert.equal(bisect(array, 5, i - 5, i), i - 0); - assert.equal(bisect(array, 6, i - 5, i), i - 0); - } - }, - "bisector(key)": { - topic: load("arrays/bisect").expression("d3.bisector"), - "left": { - topic: function(bisector) { - return bisector(function(d) { return d.key; }).left; - }, - "finds the index of an exact match": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 3}]; - assert.equal(bisect(array, 1), 0); - assert.equal(bisect(array, 2), 1); - assert.equal(bisect(array, 3), 2); - }, - "finds the index of the first match": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 2}, {key: 3}]; - assert.equal(bisect(array, 1), 0); - assert.equal(bisect(array, 2), 1); - assert.equal(bisect(array, 3), 3); - }, - "finds the insertion point of a non-exact match": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 3}]; - assert.equal(bisect(array, 0.5), 0); - assert.equal(bisect(array, 1.5), 1); - assert.equal(bisect(array, 2.5), 2); - assert.equal(bisect(array, 3.5), 3); - }, - "observes the optional lower bound": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}]; - assert.equal(bisect(array, 0, 2), 2); - assert.equal(bisect(array, 1, 2), 2); - assert.equal(bisect(array, 2, 2), 2); - assert.equal(bisect(array, 3, 2), 2); - assert.equal(bisect(array, 4, 2), 3); - assert.equal(bisect(array, 5, 2), 4); - assert.equal(bisect(array, 6, 2), 5); - }, - "observes the optional bounds": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}]; - assert.equal(bisect(array, 0, 2, 3), 2); - assert.equal(bisect(array, 1, 2, 3), 2); - assert.equal(bisect(array, 2, 2, 3), 2); - assert.equal(bisect(array, 3, 2, 3), 2); - assert.equal(bisect(array, 4, 2, 3), 3); - assert.equal(bisect(array, 5, 2, 3), 3); - assert.equal(bisect(array, 6, 2, 3), 3); - }, - "large arrays": function(bisect) { - var array = [], - i = i30; - array[i++] = {key: 1}; - array[i++] = {key: 2}; - array[i++] = {key: 3}; - array[i++] = {key: 4}; - array[i++] = {key: 5}; - assert.equal(bisect(array, 0, i - 5, i), i - 5); - assert.equal(bisect(array, 1, i - 5, i), i - 5); - assert.equal(bisect(array, 2, i - 5, i), i - 4); - assert.equal(bisect(array, 3, i - 5, i), i - 3); - assert.equal(bisect(array, 4, i - 5, i), i - 2); - assert.equal(bisect(array, 5, i - 5, i), i - 1); - assert.equal(bisect(array, 6, i - 5, i), i - 0); - } - }, - "right": { - topic: function(bisector) { - return bisector(function(d) { return d.key; }).right; - }, - "finds the index after an exact match": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 3}]; - assert.equal(bisect(array, 1), 1); - assert.equal(bisect(array, 2), 2); - assert.equal(bisect(array, 3), 3); - }, - "finds the index after the last match": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 2}, {key: 3}]; - assert.equal(bisect(array, 1), 1); - assert.equal(bisect(array, 2), 3); - assert.equal(bisect(array, 3), 4); - }, - "finds the insertion point of a non-exact match": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 3}]; - assert.equal(bisect(array, 0.5), 0); - assert.equal(bisect(array, 1.5), 1); - assert.equal(bisect(array, 2.5), 2); - assert.equal(bisect(array, 3.5), 3); - }, - "observes the optional lower bound": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}]; - assert.equal(bisect(array, 0, 2), 2); - assert.equal(bisect(array, 1, 2), 2); - assert.equal(bisect(array, 2, 2), 2); - assert.equal(bisect(array, 3, 2), 3); - assert.equal(bisect(array, 4, 2), 4); - assert.equal(bisect(array, 5, 2), 5); - assert.equal(bisect(array, 6, 2), 5); - }, - "observes the optional bounds": function(bisect) { - var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}]; - assert.equal(bisect(array, 0, 2, 3), 2); - assert.equal(bisect(array, 1, 2, 3), 2); - assert.equal(bisect(array, 2, 2, 3), 2); - assert.equal(bisect(array, 3, 2, 3), 3); - assert.equal(bisect(array, 4, 2, 3), 3); - assert.equal(bisect(array, 5, 2, 3), 3); - assert.equal(bisect(array, 6, 2, 3), 3); - }, - "large arrays": function(bisect) { - var array = [], - i = i30; - array[i++] = {key: 1}; - array[i++] = {key: 2}; - array[i++] = {key: 3}; - array[i++] = {key: 4}; - array[i++] = {key: 5}; - assert.equal(bisect(array, 0, i - 5, i), i - 5); - assert.equal(bisect(array, 1, i - 5, i), i - 4); - assert.equal(bisect(array, 2, i - 5, i), i - 3); - assert.equal(bisect(array, 3, i - 5, i), i - 2); - assert.equal(bisect(array, 4, i - 5, i), i - 1); - assert.equal(bisect(array, 5, i - 5, i), i - 0); - assert.equal(bisect(array, 6, i - 5, i), i - 0); - } - } - } -}); - -suite.export(module); diff --git a/test/arrays/descending-test.js b/test/arrays/descending-test.js deleted file mode 100644 index 2c28c75eeacc10..00000000000000 --- a/test/arrays/descending-test.js +++ /dev/null @@ -1,45 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.descending"); - -suite.addBatch({ - "descending": { - topic: load("arrays/descending").expression("d3.descending"), - "numbers": { - "returns a negative number if a > b": function(descending) { - assert.isTrue(descending(1, 0) < 0); - }, - "returns a positive number if a < b": function(descending) { - assert.isTrue(descending(0, 1) > 0); - }, - "returns zero if a == b": function(descending) { - assert.equal(descending(0, 0), 0); - }, - "returns NaN if a or b is undefined": function(descending) { - assert.isNaN(descending(0, undefined)); - assert.isNaN(descending(undefined, 0)); - assert.isNaN(descending(undefined, undefined)); - }, - "returns NaN if a or b is NaN": function(descending) { - assert.isNaN(descending(0, NaN)); - assert.isNaN(descending(NaN, 0)); - assert.isNaN(descending(NaN, NaN)); - } - }, - "strings": { - "returns a negative number if a > b": function(descending) { - assert.isTrue(descending("b", "a") < 0); - }, - "returns a positive number if a < b": function(descending) { - assert.isTrue(descending("a", "b") > 0); - }, - "returns zero if a == b": function(descending) { - assert.equal(descending("a", "a"), 0); - } - } - } -}); - -suite.export(module); diff --git a/test/arrays/entries-test.js b/test/arrays/entries-test.js deleted file mode 100644 index 32f53f919b9d2d..00000000000000 --- a/test/arrays/entries-test.js +++ /dev/null @@ -1,39 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.entries"); - -suite.addBatch({ - "entries": { - topic: load("arrays/entries").expression("d3.entries"), - "enumerates every entry": function(entries) { - assert.deepEqual(entries({a: 1, b: 2}), [ - {key: "a", value: 1}, - {key: "b", value: 2} - ]); - }, - "includes entries defined on prototypes": function(entries) { - function abc() { - this.a = 1; - this.b = 2; - } - abc.prototype.c = 3; - assert.deepEqual(entries(new abc()), [ - {key: "a", value: 1}, - {key: "b", value: 2}, - {key: "c", value: 3} - ]); - }, - "includes null or undefined values": function(entries) { - var v = entries({a: undefined, b: null, c: NaN}); - assert.equal(v.length, 3); - assert.deepEqual(v[0], {key: "a", value: undefined}); - assert.deepEqual(v[1], {key: "b", value: null}); - assert.equal(v[2].key, "c"); - assert.isNaN(v[2].value); - } - } -}); - -suite.export(module); diff --git a/test/arrays/extent-test.js b/test/arrays/extent-test.js deleted file mode 100644 index bfdfa5fd4a4aad..00000000000000 --- a/test/arrays/extent-test.js +++ /dev/null @@ -1,50 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.extent"); - -suite.addBatch({ - "extent": { - topic: load("arrays/extent").expression("d3.extent"), - "returns the numeric extent for numbers": function(extent) { - assert.deepEqual(extent([1]), [1, 1]); - assert.deepEqual(extent([5, 1, 2, 3, 4]), [1, 5]); - assert.deepEqual(extent([20, 3]), [3, 20]); - assert.deepEqual(extent([3, 20]), [3, 20]); - }, - "returns the lexicographic extent for strings": function(extent) { - assert.deepEqual(extent(["c", "a", "b"]), ["a", "c"]); - assert.deepEqual(extent(["20", "3"]), ["20", "3"]); - assert.deepEqual(extent(["3", "20"]), ["20", "3"]); - }, - "ignores null, undefined and NaN": function(extent) { - var o = {valueOf: function() { return NaN; }}; - assert.deepEqual(extent([NaN, 1, 2, 3, 4, 5]), [1, 5]); - assert.deepEqual(extent([o, 1, 2, 3, 4, 5]), [1, 5]); - assert.deepEqual(extent([1, 2, 3, 4, 5, NaN]), [1, 5]); - assert.deepEqual(extent([1, 2, 3, 4, 5, o]), [1, 5]); - assert.deepEqual(extent([10, null, 3, undefined, 5, NaN]), [3, 10]); - assert.deepEqual(extent([-1, null, -3, undefined, -5, NaN]), [-5, -1]); - }, - "compares heterogenous types as numbers": function(extent) { - assert.deepEqual(extent([20, "3"]), ["3", 20]); - assert.deepEqual(extent(["20", 3]), [3, "20"]); - assert.deepEqual(extent([3, "20"]), [3, "20"]); - assert.deepEqual(extent(["3", 20]), ["3", 20]); - }, - "returns undefined for empty array": function(extent) { - assert.deepEqual(extent([]), [undefined, undefined]); - assert.deepEqual(extent([null]), [undefined, undefined]); - assert.deepEqual(extent([undefined]), [undefined, undefined]); - assert.deepEqual(extent([NaN]), [undefined, undefined]); - assert.deepEqual(extent([NaN, NaN]), [undefined, undefined]); - }, - "applies the optional accessor function exactly once": function(extent) { - var i = 10; - assert.deepEqual(extent([0,1,2,3], function() { return ++i; }), [11, 14]); - } - } -}); - -suite.export(module); diff --git a/test/arrays/keys-test.js b/test/arrays/keys-test.js deleted file mode 100644 index c11bda697b03ad..00000000000000 --- a/test/arrays/keys-test.js +++ /dev/null @@ -1,27 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.keys"); - -suite.addBatch({ - "keys": { - topic: load("arrays/keys").expression("d3.keys"), - "enumerates every defined key": function(keys) { - assert.deepEqual(keys({a: 1, b: 1}), ["a", "b"]); - }, - "includes keys defined on prototypes": function(keys) { - function abc() { - this.a = 1; - this.b = 2; - } - abc.prototype.c = 3; - assert.deepEqual(keys(new abc()), ["a", "b", "c"]); - }, - "includes keys with null or undefined values": function(keys) { - assert.deepEqual(keys({a: undefined, b: null, c: NaN}), ["a", "b", "c"]); - } - } -}); - -suite.export(module); diff --git a/test/arrays/map-test.js b/test/arrays/map-test.js deleted file mode 100644 index dae0fd909c0808..00000000000000 --- a/test/arrays/map-test.js +++ /dev/null @@ -1,222 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.map"); - -suite.addBatch({ - "map": { - topic: load("arrays/map").expression("d3.map"), - "constructor": { - "map() returns an empty map": function(map) { - var m = map(); - assert.deepEqual(m.keys(), []); - }, - "map(null) returns an empty map": function(map) { - var m = map(null); - assert.deepEqual(m.keys(), []); - }, - "map(object) copies enumerable keys": function(map) { - var m = map({foo: 42}); - assert.isTrue(m.has("foo")); - assert.equal(m.get("foo"), 42); - var m = map(Object.create(null, {foo: {value: 42, enumerable: true}})); - assert.isTrue(m.has("foo")); - assert.equal(m.get("foo"), 42); - }, - "map(object) copies inherited keys": function(map) { - function Foo() {} - Foo.prototype.foo = 42; - var m = map(Object.create({foo: 42})); - assert.isTrue(m.has("foo")); - assert.equal(m.get("foo"), 42); - var m = map(new Foo()); - assert.isTrue(m.has("foo")); - assert.equal(m.get("foo"), 42); - }, - "map(object) does not copy non-enumerable keys": function(map) { - var m = map({__proto__: 42}); // because __proto__ isn't enumerable - assert.isFalse(m.has("__proto__")); - assert.isUndefined(m.get("__proto__")); - var m = map(Object.create(null, {foo: {value: 42, enumerable: false}})); - assert.isFalse(m.has("foo")); - assert.isUndefined(m.get("foo")); - }, - "map(map) copies the given map": function(map) { - var a = map({foo: 42}), - b = map(a); - assert.isTrue(b.has("foo")); - assert.equal(b.get("foo"), 42); - a.set("bar", true); - assert.isFalse(b.has("bar")); - } - }, - "forEach": { - "empty maps have an empty keys array": function(map) { - var m = map(); - assert.deepEqual(m.entries(), []); - m.set("foo", "bar"); - assert.deepEqual(m.entries(), [{key: "foo", value: "bar"}]); - m.remove("foo"); - assert.deepEqual(m.entries(), []); - }, - "keys are returned in arbitrary order": function(map) { - var m = map({foo: 1, bar: "42"}); - assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "42"}, {key: "foo", value: 1}]); - var m = map({bar: "42", foo: 1}); - assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "42"}, {key: "foo", value: 1}]); - }, - "observes changes via set and remove": function(map) { - var m = map({foo: 1, bar: "42"}); - assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "42"}, {key: "foo", value: 1}]); - m.remove("foo"); - assert.deepEqual(m.entries(), [{key: "bar", value: "42"}]); - m.set("bar", "bar"); - assert.deepEqual(m.entries(), [{key: "bar", value: "bar"}]); - m.set("foo", "foo"); - assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "bar"}, {key: "foo", value: "foo"}]); - m.remove("bar"); - assert.deepEqual(m.entries(), [{key: "foo", value: "foo"}]); - m.remove("foo"); - assert.deepEqual(m.entries(), []); - m.remove("foo"); - assert.deepEqual(m.entries(), []); - } - }, - "keys": { - "returns an array of string keys": function(map) { - var m = map({foo: 1, bar: "42"}); - assert.deepEqual(m.keys().sort(), ["bar", "foo"]); - } - }, - "values": { - "returns an array of arbitrary values": function(map) { - var m = map({foo: 1, bar: "42"}); - assert.deepEqual(m.values().sort(), [1, "42"]); - } - }, - "entries": { - "returns an array of key-value objects": function(map) { - var m = map({foo: 1, bar: "42"}); - assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "42"}, {key: "foo", value: 1}]); - } - }, - "has": { - "empty maps do not have object built-ins": function(map) { - var m = map(); - assert.isFalse(m.has("__proto__")); - assert.isFalse(m.has("hasOwnProperty")); - }, - "can has keys using built-in names": function(map) { - var m = map(); - m.set("__proto__", 42); - assert.isTrue(m.has("__proto__")); - }, - "can has keys with null or undefined properties": function(map) { - var m = map(); - m.set("", ""); - m.set("null", null); - m.set("undefined", undefined); - assert.isTrue(m.has("")); - assert.isTrue(m.has("null")); - assert.isTrue(m.has("undefined")); - }, - "coerces keys to strings": function(map) { - var m = map({"42": "foo", "null": 1, "undefined": 2}); - assert.isTrue(m.has(42)); - assert.isTrue(m.has(null)); - assert.isTrue(m.has(undefined)); - }, - "returns the latest value": function(map) { - var m = map({foo: 42}); - assert.isTrue(m.has("foo")); - m.set("foo", 43); - assert.isTrue(m.has("foo")); - m.remove("foo"); - assert.isFalse(m.has("foo")); - m.set("foo", "bar"); - assert.isTrue(m.has("foo")); - }, - "returns undefined for missing keys": function(map) { - var m = map({foo: 42}); - assert.isFalse(m.has("bar")); - } - }, - "get": { - "empty maps do not have object built-ins": function(map) { - var m = map(); - assert.isUndefined(m.get("__proto__")); - assert.isUndefined(m.get("hasOwnProperty")); - }, - "can get keys using built-in names": function(map) { - var m = map(); - m.set("__proto__", 42); - assert.equal(m.get("__proto__"), 42); - }, - "coerces keys to strings": function(map) { - var m = map({"42": 1, "null": 2, "undefined": 3}); - assert.equal(m.get(42), 1); - assert.equal(m.get(null), 2); - assert.equal(m.get(undefined), 3); - }, - "returns the latest value": function(map) { - var m = map({foo: 42}); - assert.equal(m.get("foo"), 42); - m.set("foo", 43); - assert.equal(m.get("foo"), 43); - m.remove("foo"); - assert.isUndefined(m.get("foo")); - m.set("foo", "bar"); - assert.equal(m.get("foo"), "bar"); - }, - "returns undefined for missing keys": function(map) { - var m = map({foo: 42}); - assert.isUndefined(m.get("bar")); - } - }, - "set": { - "returns the set value": function(map) { - var m = map(); - assert.equal(m.set("foo", 42), 42); - }, - "can set keys using built-in names": function(map) { - var m = map(); - m.set("__proto__", 42); - assert.equal(m.get("__proto__"), 42); - }, - "coerces keys to strings": function(map) { - var m = map(); - m.set(42, 1); - assert.equal(m.get(42), 1); - m.set(null, 2); - assert.equal(m.get(null), 2); - m.set(undefined, 3); - assert.equal(m.get(undefined), 3); - assert.deepEqual(m.keys().sort(), ["42", "null", "undefined"]); - }, - "can replace values": function(map) { - var m = map({foo: 42}); - assert.equal(m.get("foo"), 42); - m.set("foo", 43); - assert.equal(m.get("foo"), 43); - m.set("foo", "bar"); - assert.equal(m.get("foo"), "bar"); - }, - "can set null, undefined or empty string values": function(map) { - var m = map(); - m.set("", ""); - m.set("null", null); - m.set("undefined", undefined); - assert.equal(m.get(""), ""); - assert.isNull(m.get("null")); - assert.isUndefined(m.get("undefined")); - } - } - } -}); - -function ascendingByKey(a, b) { - return a.key.localeCompare(b.key); -} - -suite.export(module); diff --git a/test/arrays/max-test.js b/test/arrays/max-test.js deleted file mode 100644 index 2403ac28a55cc7..00000000000000 --- a/test/arrays/max-test.js +++ /dev/null @@ -1,51 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.max"); - -suite.addBatch({ - "max": { - topic: load("arrays/max").expression("d3.max"), - "returns the greatest numeric value for numbers": function(max) { - assert.equal(max([1]), 1); - assert.equal(max([5, 1, 2, 3, 4]), 5); - assert.equal(max([20, 3]), 20); - assert.equal(max([3, 20]), 20); - }, - "returns the greatest lexicographic value for strings": function(max) { - assert.equal(max(["c", "a", "b"]), "c"); - assert.equal(max(["20", "3"]), "3"); - assert.equal(max(["3", "20"]), "3"); - }, - "ignores null, undefined and NaN": function(max) { - var o = {valueOf: function() { return NaN; }}; - assert.equal(max([NaN, 1, 2, 3, 4, 5]), 5); - assert.equal(max([o, 1, 2, 3, 4, 5]), 5); - assert.equal(max([1, 2, 3, 4, 5, NaN]), 5); - assert.equal(max([1, 2, 3, 4, 5, o]), 5); - assert.equal(max([10, null, 3, undefined, 5, NaN]), 10); - assert.equal(max([-1, null, -3, undefined, -5, NaN]), -1); - }, - "compares heterogenous types as numbers": function(max) { - assert.strictEqual(max([20, "3"]), 20); - assert.strictEqual(max(["20", 3]), "20"); - assert.strictEqual(max([3, "20"]), "20"); - assert.strictEqual(max(["3", 20]), 20); - }, - "returns undefined for empty array": function(max) { - assert.isUndefined(max([])); - assert.isUndefined(max([null])); - assert.isUndefined(max([undefined])); - assert.isUndefined(max([NaN])); - assert.isUndefined(max([NaN, NaN])); - }, - "applies the optional accessor function": function(max) { - assert.equal(max([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return _.min(d); }), 2); - assert.equal(max([1, 2, 3, 4, 5], function(d, i) { return i; }), 4); - } - } -}); - -suite.export(module); diff --git a/test/arrays/mean-test.js b/test/arrays/mean-test.js deleted file mode 100644 index 26cb28e0b08d64..00000000000000 --- a/test/arrays/mean-test.js +++ /dev/null @@ -1,39 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.mean"); - -suite.addBatch({ - "mean": { - topic: load("arrays/mean").expression("d3.mean"), - "returns the mean value for numbers": function(mean) { - assert.equal(mean([1]), 1); - assert.equal(mean([5, 1, 2, 3, 4]), 3); - assert.equal(mean([20, 3]), 11.5); - assert.equal(mean([3, 20]), 11.5); - }, - "ignores null, undefined and NaN": function(mean) { - assert.equal(mean([NaN, 1, 2, 3, 4, 5]), 3); - assert.equal(mean([1, 2, 3, 4, 5, NaN]), 3); - assert.equal(mean([10, null, 3, undefined, 5, NaN]), 6); - }, - "can handle large numbers without overflowing": function(mean) { - assert.equal(mean([Number.MAX_VALUE, Number.MAX_VALUE]), Number.MAX_VALUE); - assert.equal(mean([-Number.MAX_VALUE, -Number.MAX_VALUE]), -Number.MAX_VALUE); - }, - "returns undefined for empty array": function(mean) { - assert.isUndefined(mean([])); - assert.isUndefined(mean([null])); - assert.isUndefined(mean([undefined])); - assert.isUndefined(mean([NaN])); - assert.isUndefined(mean([NaN, NaN])); - }, - "applies the optional accessor function": function(mean) { - assert.equal(mean([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return mean(d); }), 4.5); - assert.equal(mean([1, 2, 3, 4, 5], function(d, i) { return i; }), 2); - } - } -}); - -suite.export(module); diff --git a/test/arrays/median-test.js b/test/arrays/median-test.js deleted file mode 100644 index 8b1ef40b211414..00000000000000 --- a/test/arrays/median-test.js +++ /dev/null @@ -1,39 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.median"); - -suite.addBatch({ - "median": { - topic: load("arrays/median").expression("d3.median"), - "returns the median value for numbers": function(median) { - assert.equal(median([1]), 1); - assert.equal(median([5, 1, 2, 3, 4]), 3); - assert.equal(median([20, 3]), 11.5); - assert.equal(median([3, 20]), 11.5); - }, - "ignores null, undefined and NaN": function(median) { - assert.equal(median([NaN, 1, 2, 3, 4, 5]), 3); - assert.equal(median([1, 2, 3, 4, 5, NaN]), 3); - assert.equal(median([10, null, 3, undefined, 5, NaN]), 5); - }, - "can handle large numbers without overflowing": function(median) { - assert.equal(median([Number.MAX_VALUE, Number.MAX_VALUE]), Number.MAX_VALUE); - assert.equal(median([-Number.MAX_VALUE, -Number.MAX_VALUE]), -Number.MAX_VALUE); - }, - "returns undefined for empty array": function(median) { - assert.isUndefined(median([])); - assert.isUndefined(median([null])); - assert.isUndefined(median([undefined])); - assert.isUndefined(median([NaN])); - assert.isUndefined(median([NaN, NaN])); - }, - "applies the optional accessor function": function(median) { - assert.equal(median([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return median(d); }), 4.5); - assert.equal(median([1, 2, 3, 4, 5], function(d, i) { return i; }), 2); - } - } -}); - -suite.export(module); diff --git a/test/arrays/merge-test.js b/test/arrays/merge-test.js deleted file mode 100644 index 86c705eeefe819..00000000000000 --- a/test/arrays/merge-test.js +++ /dev/null @@ -1,26 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.merge"); - -suite.addBatch({ - "merge": { - topic: load("arrays/merge").expression("d3.merge"), - "merges an array of arrays": function(merge) { - var a = {}, b = {}, c = {}, d = {}, e = {}, f = {}; - assert.deepEqual(merge([[a], [b, c], [d, e, f]]), [a, b, c, d, e, f]); - }, - "returns a new array": function(merge) { - var input = [[1, 2, 3], [4, 5], [6]]; - assert.isFalse(merge(input) === input); - }, - "does not modify the input arrays": function(merge) { - var input = [[1, 2, 3], [4, 5], [6]]; - merge(input); - assert.deepEqual(input, [[1, 2, 3], [4, 5], [6]]); - } - } -}); - -suite.export(module); diff --git a/test/arrays/min-test.js b/test/arrays/min-test.js deleted file mode 100644 index 5fe331bb19c14d..00000000000000 --- a/test/arrays/min-test.js +++ /dev/null @@ -1,51 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.min"); - -suite.addBatch({ - "min": { - topic: load("arrays/min").expression("d3.min"), - "returns the least numeric value for numbers": function(min) { - assert.equal(min([1]), 1); - assert.equal(min([5, 1, 2, 3, 4]), 1); - assert.equal(min([20, 3]), 3); - assert.equal(min([3, 20]), 3); - }, - "returns the least lexicographic value for strings": function(min) { - assert.equal(min(["c", "a", "b"]), "a"); - assert.equal(min(["20", "3"]), "20"); - assert.equal(min(["3", "20"]), "20"); - }, - "ignores null, undefined and NaN": function(min) { - var o = {valueOf: function() { return NaN; }}; - assert.equal(min([NaN, 1, 2, 3, 4, 5]), 1); - assert.equal(min([o, 1, 2, 3, 4, 5]), 1); - assert.equal(min([1, 2, 3, 4, 5, NaN]), 1); - assert.equal(min([1, 2, 3, 4, 5, o]), 1); - assert.equal(min([10, null, 3, undefined, 5, NaN]), 3); - assert.equal(min([-1, null, -3, undefined, -5, NaN]), -5); - }, - "compares heterogenous types as numbers": function(min) { - assert.strictEqual(min([20, "3"]), "3"); - assert.strictEqual(min(["20", 3]), 3); - assert.strictEqual(min([3, "20"]), 3); - assert.strictEqual(min(["3", 20]), "3"); - }, - "returns undefined for empty array": function(min) { - assert.isUndefined(min([])); - assert.isUndefined(min([null])); - assert.isUndefined(min([undefined])); - assert.isUndefined(min([NaN])); - assert.isUndefined(min([NaN, NaN])); - }, - "applies the optional accessor function": function(min) { - assert.equal(min([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return _.max(d); }), 5); - assert.equal(min([1, 2, 3, 4, 5], function(d, i) { return i; }), 0); - } - } -}); - -suite.export(module); diff --git a/test/arrays/nest-test.js b/test/arrays/nest-test.js deleted file mode 100644 index 13d9001d2dda50..00000000000000 --- a/test/arrays/nest-test.js +++ /dev/null @@ -1,256 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.nest"); - -suite.addBatch({ - "entries": { - topic: load("arrays/nest").expression("d3.nest"), - "returns an array of each distinct key in arbitrary order": function(nest) { - var keys = nest() - .key(function(d) { return d.foo; }) - .entries([{foo: 1}, {foo: 1}, {foo: 2}]) - .map(function(d) { return d.key; }) - .sort(_.ascending); - assert.deepEqual(keys, ["1", "2"]); - }, - "each entry is a key-values object, with values in input order": function(nest) { - var entries = nest() - .key(function(d) { return d.foo; }) - .entries([{foo: 1, bar: 0}, {foo: 2}, {foo: 1, bar: 1}]); - assert.deepEqual(entries, [ - {key: "1", values: [{foo: 1, bar: 0}, {foo: 1, bar: 1}]}, - {key: "2", values: [{foo: 2}]} - ]); - }, - "keys can be sorted using an optional comparator": function(nest) { - var keys = nest() - .key(function(d) { return d.foo; }).sortKeys(_.descending) - .entries([{foo: 1}, {foo: 1}, {foo: 2}]) - .map(function(d) { return d.key; }); - assert.deepEqual(keys, ["2", "1"]); - }, - "values can be sorted using an optional comparator": function(nest) { - var entries = nest() - .key(function(d) { return d.foo; }) - .sortValues(function(a, b) { return a.bar - b.bar; }) - .entries([{foo: 1, bar: 2}, {foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 2}]); - assert.deepEqual(entries, [ - {key: "1", values: [{foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 1, bar: 2}]}, - {key: "2", values: [{foo: 2}]} - ]); - }, - "values can be aggregated using an optional rollup": function(nest) { - var entries = nest() - .key(function(d) { return d.foo; }) - .rollup(function(values) { return _.sum(values, function(d) { return d.bar; }); }) - .entries([{foo: 1, bar: 2}, {foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 2}]); - assert.deepEqual(entries, [ - {key: "1", values: 3}, - {key: "2", values: 0} - ]); - }, - "multiple key functions can be specified": function(nest) { - var entries = nest() - .key(function(d) { return d[0]; }).sortKeys(_.ascending) - .key(function(d) { return d[1]; }).sortKeys(_.ascending) - .entries([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]); - assert.deepEqual(entries, [ - {key: "0", values: [ - {key: "1", values: [[0, 1]]}, - {key: "2", values: [[0, 2], [0, 2]]} - ]}, - {key: "1", values: [ - {key: "1", values: [[1, 1]]}, - {key: "2", values: [[1, 2]]} - ]} - ]); - }, - "the rollup function only applies to leaf values": function(nest) { - var entries = nest() - .key(function(d) { return d[0]; }).sortKeys(_.ascending) - .key(function(d) { return d[1]; }).sortKeys(_.ascending) - .rollup(function(values) { return values.length; }) - .entries([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]); - assert.deepEqual(entries, [ - {key: "0", values: [ - {key: "1", values: 1}, - {key: "2", values: 2} - ]}, - {key: "1", values: [ - {key: "1", values: 1}, - {key: "2", values: 1} - ]} - ]); - }, - "the value comparator only applies to leaf values": function(nest) { - var entries = nest() - .key(function(d) { return d[0]; }).sortKeys(_.ascending) - .key(function(d) { return d[1]; }).sortKeys(_.ascending) - .sortValues(function(a, b) { return a[2] - b[2]; }) - .entries([[0, 1], [0, 2, 1], [1, 1], [1, 2], [0, 2, 0]]); - assert.deepEqual(entries, [ - {key: "0", values: [ - {key: "1", values: [[0, 1]]}, - {key: "2", values: [[0, 2, 0], [0, 2, 1]]} - ]}, - {key: "1", values: [ - {key: "1", values: [[1, 1]]}, - {key: "2", values: [[1, 2]]} - ]} - ]); - }, - "the key comparator only applies to the last-specified key": function(nest) { - var entries = nest() - .key(function(d) { return d[0]; }).sortKeys(_.ascending) - .key(function(d) { return d[1]; }).sortKeys(_.descending) - .entries([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]); - assert.deepEqual(entries, [ - {key: "0", values: [ - {key: "2", values: [[0, 2], [0, 2]]}, - {key: "1", values: [[0, 1]]} - ]}, - {key: "1", values: [ - {key: "2", values: [[1, 2]]}, - {key: "1", values: [[1, 1]]} - ]} - ]); - var entries = nest() - .key(function(d) { return d[0]; }).sortKeys(_.descending) - .key(function(d) { return d[1]; }).sortKeys(_.ascending) - .entries([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]); - assert.deepEqual(entries, [ - {key: "1", values: [ - {key: "1", values: [[1, 1]]}, - {key: "2", values: [[1, 2]]} - ]}, - {key: "0", values: [ - {key: "1", values: [[0, 1]]}, - {key: "2", values: [[0, 2], [0, 2]]} - ]} - ]); - }, - "if no keys are specified, the input array is returned": function(nest) { - var array = [new Object()]; - assert.strictEqual(nest().entries(array), array); - } - } -}); - -suite.addBatch({ - "map": { - topic: load("arrays/nest").expression("d3.nest"), - "returns a map of each distinct key": function(nest) { - var map = nest() - .key(function(d) { return d.foo; }) - .map([{foo: 1, bar: 0}, {foo: 2}, {foo: 1, bar: 1}]); - assert.deepEqual(map, { - "1": [{foo: 1, bar: 0}, {foo: 1, bar: 1}], - "2": [{foo: 2}] - }); - }, - "values can be sorted using an optional comparator": function(nest) { - var map = nest() - .key(function(d) { return d.foo; }) - .sortValues(function(a, b) { return a.bar - b.bar; }) - .map([{foo: 1, bar: 2}, {foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 2}]); - assert.deepEqual(map, { - "1": [{foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 1, bar: 2}], - "2": [{foo: 2}] - }); - }, - "values can be aggregated using an optional rollup": function(nest) { - var map = nest() - .key(function(d) { return d.foo; }) - .rollup(function(values) { return _.sum(values, function(d) { return d.bar; }); }) - .map([{foo: 1, bar: 2}, {foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 2}]); - assert.deepEqual(map, { - "1": 3, - "2": 0 - }); - }, - "multiple key functions can be specified": function(nest) { - var map = nest() - .key(function(d) { return d[0]; }).sortKeys(_.ascending) - .key(function(d) { return d[1]; }).sortKeys(_.ascending) - .map([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]); - assert.deepEqual(map, { - "0": { - "1": [[0, 1]], - "2": [[0, 2], [0, 2]] - }, - "1": { - "1": [[1, 1]], - "2": [[1, 2]] - } - }); - }, - "the rollup function only applies to leaf values": function(nest) { - var map = nest() - .key(function(d) { return d[0]; }).sortKeys(_.ascending) - .key(function(d) { return d[1]; }).sortKeys(_.ascending) - .rollup(function(values) { return values.length; }) - .map([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]); - assert.deepEqual(map, { - "0": { - "1": 1, - "2": 2 - }, - "1": { - "1": 1, - "2": 1 - } - }); - }, - "the value comparator only applies to leaf values": function(nest) { - var map = nest() - .key(function(d) { return d[0]; }).sortKeys(_.ascending) - .key(function(d) { return d[1]; }).sortKeys(_.ascending) - .sortValues(function(a, b) { return a[2] - b[2]; }) - .map([[0, 1], [0, 2, 1], [1, 1], [1, 2], [0, 2, 0]]); - assert.deepEqual(map, { - "0": { - "1": [[0, 1]], - "2": [[0, 2, 0], [0, 2, 1]] - }, - "1": { - "1": [[1, 1]], - "2": [[1, 2]] - } - }); - }, - "if no keys are specified, the input array is returned": function(nest) { - var array = [new Object()]; - assert.strictEqual(nest().map(array), array); - }, - "handles keys that are built-in prototype properties": function(nest) { - var map = nest() - .key(String) - .map(["hasOwnProperty"]); // but note __proto__ wouldn’t work! - assert.deepEqual(map, {hasOwnProperty: ["hasOwnProperty"]}); - }, - "a custom map implementation can be specified": function(nest) { - var map = nest() - .key(String) - .map(["hasOwnProperty", "__proto__"], _.map); - assert.deepEqual(map.entries(), [ - {key: "hasOwnProperty", value: ["hasOwnProperty"]}, - {key: "__proto__", value: ["__proto__"]} - ]); - }, - "the custom map implementation works on multiple levels of nesting": function(nest) { - var map = nest() - .key(function(d) { return d.foo; }) - .key(function(d) { return d.bar; }) - .map([{foo: 42, bar: "red"}], _.map); - assert.deepEqual(map.keys(), ["42"]); - assert.deepEqual(map.get("42").keys(), ["red"]); - assert.deepEqual(map.get("42").values(), [[{foo: 42, bar: "red"}]]); - assert.deepEqual(map.get("42").entries(), [{key: "red", value: [{foo: 42, bar: "red"}]}]); - } - } -}); - -suite.export(module); diff --git a/test/arrays/pairs-test.js b/test/arrays/pairs-test.js deleted file mode 100644 index 23b07fac7d5d2a..00000000000000 --- a/test/arrays/pairs-test.js +++ /dev/null @@ -1,27 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.pairs"); - -suite.addBatch({ - "pairs": { - topic: load("arrays/pairs").expression("d3.pairs"), - "returns the empty array if input array has length less than two": function(pairs) { - assert.deepEqual(pairs([]), []); - assert.deepEqual(pairs([1]), []); - }, - "returns pairs of adjacent elements in the given array": function(pairs) { - assert.deepEqual(pairs([1, 2]), [[1, 2]]); - assert.deepEqual(pairs([1, 2, 3]), [[1, 2], [2, 3]]); - var a = {}, b = {}, c = {}, d = {}; - assert.deepEqual(pairs([a, b, c, d]), [[a, b], [b, c], [c, d]]); - }, - "includes null or undefined elements in pairs": function(pairs) { - assert.deepEqual(pairs([1, null, 2]), [[1, null], [null, 2]]); - assert.deepEqual(pairs([1, 2, undefined]), [[1, 2], [2, undefined]]); - } - } -}); - -suite.export(module); diff --git a/test/arrays/permute-test.js b/test/arrays/permute-test.js deleted file mode 100644 index 4f3d01ed182c27..00000000000000 --- a/test/arrays/permute-test.js +++ /dev/null @@ -1,49 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.permute"); - -suite.addBatch({ - "permute": { - topic: load("arrays/permute").expression("d3.permute"), - "permutes according to the specified index": function(permute) { - assert.deepEqual(permute([3, 4, 5], [2, 1, 0]), [5, 4, 3]); - assert.deepEqual(permute([3, 4, 5], [2, 0, 1]), [5, 3, 4]); - assert.deepEqual(permute([3, 4, 5], [0, 1, 2]), [3, 4, 5]); - }, - "does not modify the input array": function(permute) { - var input = [3, 4, 5]; - permute(input, [2, 1, 0]); - assert.deepEqual(input, [3, 4, 5]); - }, - "can duplicate input values": function(permute) { - assert.deepEqual(permute([3, 4, 5], [0, 1, 0]), [3, 4, 3]); - assert.deepEqual(permute([3, 4, 5], [2, 2, 2]), [5, 5, 5]); - assert.deepEqual(permute([3, 4, 5], [0, 1, 1]), [3, 4, 4]); - }, - "can return more elements": function(permute) { - assert.deepEqual(permute([3, 4, 5], [0, 0, 1, 2]), [3, 3, 4, 5]); - assert.deepEqual(permute([3, 4, 5], [0, 1, 1, 1]), [3, 4, 4, 4]); - }, - "can return fewer elements": function(permute) { - assert.deepEqual(permute([3, 4, 5], [0]), [3]); - assert.deepEqual(permute([3, 4, 5], [1, 2]), [4, 5]); - assert.deepEqual(permute([3, 4, 5], []), []); - }, - "can return undefined elements": function(permute) { - var v1 = permute([3, 4, 5], [10]); - assert.equal(v1.length, 1); - assert.isUndefined(v1[0]); - var v2 = permute([3, 4, 5], [-1]); - assert.equal(v2.length, 1); - assert.isUndefined(v2[0]); - var v3 = permute([3, 4, 5], [0, -1]); - assert.equal(v3.length, 2); - assert.equal(v3[0], 3); - assert.isUndefined(v3[1]); - } - } -}); - -suite.export(module); diff --git a/test/arrays/quantile-test.js b/test/arrays/quantile-test.js deleted file mode 100644 index 2cbade9cda2bf6..00000000000000 --- a/test/arrays/quantile-test.js +++ /dev/null @@ -1,56 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.quantile"); - -suite.addBatch({ - "quantile": { - topic: load("arrays/quantile").expression("d3.quantile"), - "requires sorted numeric input": function(quantile) { - assert.equal(quantile([1, 2, 3, 4], 0), 1); - assert.equal(quantile([1, 2, 3, 4], 1), 4); - assert.equal(quantile([4, 3, 2, 1], 0), 4); - assert.equal(quantile([4, 3, 2, 1], 1), 1); - }, - "uses the R-7 algorithm": function(quantile) { - var data = [3, 6, 7, 8, 8, 10, 13, 15, 16, 20]; - assert.equal(quantile(data, 0), 3); - assert.equal(quantile(data, .25), 7.25); - assert.equal(quantile(data, .5), 9); - assert.equal(quantile(data, .75), 14.5); - assert.equal(quantile(data, 1), 20); - var data = [3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20]; - assert.equal(quantile(data, 0), 3); - assert.equal(quantile(data, .25), 7.5); - assert.equal(quantile(data, .5), 9); - assert.equal(quantile(data, .75), 14); - assert.equal(quantile(data, 1), 20); - }, - "coerces values to numbers": function(quantile) { - var strings = ["1", "2", "3", "4"]; - assert.strictEqual(quantile(strings, 1/3), 2); - assert.strictEqual(quantile(strings, 1/2), 2.5); - assert.strictEqual(quantile(strings, 2/3), 3); - var dates = [new Date(2011, 0, 1), new Date(2012, 0, 1)]; - assert.strictEqual(quantile(dates, 0), +new Date(2011, 0, 1)); - assert.strictEqual(quantile(dates, 1/2), +new Date(2011, 6, 2, 13)); - assert.strictEqual(quantile(dates, 1), +new Date(2012, 0, 1)); - }, - "returns an exact value for integer p-values": function(quantile) { - var data = [1, 2, 3, 4]; - assert.equal(quantile(data, 1/3), 2); - assert.equal(quantile(data, 2/3), 3); - }, - "returns the first value for p = 0": function(quantile) { - var data = [1, 2, 3, 4]; - assert.equal(quantile(data, 0), 1); - }, - "returns the last value for p = 1": function(quantile) { - var data = [1, 2, 3, 4]; - assert.equal(quantile(data, 1), 4); - } - } -}); - -suite.export(module); diff --git a/test/arrays/range-test.js b/test/arrays/range-test.js deleted file mode 100644 index 35619545d5a9fc..00000000000000 --- a/test/arrays/range-test.js +++ /dev/null @@ -1,99 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.range"); - -suite.addBatch({ - "range": { - topic: load("arrays/range").expression("d3.range"), - "start is an inclusive lower bound": function(range) { - assert.equal(range(5)[0], 0); - assert.equal(range(1, 5)[0], 1); - assert.equal(range(5, 1, -1)[0], 5); - }, - "stop is an exclusive upper bound": function(range) { - assert.equal(range(5)[4], 4); - assert.equal(range(1, 5)[3], 4); - assert.equal(range(5, 1, -1)[3], 2); - }, - "with one argument, returns integers [0 … stop)": function(range) { - assert.deepEqual(range(0), []); - assert.deepEqual(range(1), [0]); - assert.deepEqual(range(5), [0, 1, 2, 3, 4]); - }, - "with two arguments, returns integers [start … stop)": function(range) { - assert.deepEqual(range(0, 5), [0, 1, 2, 3, 4]); - assert.deepEqual(range(5, 9), [5, 6, 7, 8]); - }, - "with three arguments, returns start + k * step": function(range) { - assert.deepEqual(range(0, 5, 1), [0, 1, 2, 3, 4]); - assert.deepEqual(range(5, 9, .5), [5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5]); - assert.deepEqual(range(5, 8.5, .5), [5, 5.5, 6, 6.5, 7, 7.5, 8]); - assert.deepEqual(range(2, 0, -.5), [2, 1.5, 1, .5]); - }, - "handles fractional steps without rounding errors": function(range) { - assert.deepEqual(range(0, 0.5, 0.1), [0, 0.1, 0.2, 0.3, 0.4]); - assert.deepEqual(range(-2, -1.2, 0.1), [-2, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3]); - }, - "handles extremely small steps without rounding errors": function(range) { - assert.deepEqual(range(2.1e-31, 5e-31, 1.1e-31), [2.1e-31, 3.2e-31, 4.3e-31]); - }, - "handles extremely large steps without rounding errors": function(range) { - assert.deepEqual(range(1e300, 2e300, 0.3e300), [1e300, 1.3e300, 1.6e300, 1.9e300]); - }, - "returns an ascending range if step is positive": function(range) { - assert.deepEqual(range(0, 5, 1), [0, 1, 2, 3, 4]); - }, - "returns a descending range if step is negative": function(range) { - assert.deepEqual(range(5, 0, -1), [5, 4, 3, 2, 1]); - }, - "returns an empty range if start, stop or step are NaN": function(range) { - assert.isEmpty(range(0, NaN)); - assert.isEmpty(range(1, NaN)); - assert.isEmpty(range(-1, NaN)); - assert.isEmpty(range(0, undefined)); - assert.isEmpty(range(1, undefined)); - assert.isEmpty(range(-1, undefined)); - assert.isEmpty(range(NaN, 0)); - assert.isEmpty(range(NaN, 1)); - assert.isEmpty(range(NaN, -1)); - assert.isEmpty(range(undefined, 0)); - assert.isEmpty(range(undefined, 1)); - assert.isEmpty(range(undefined, -1)); - assert.isEmpty(range(NaN, NaN)); - assert.isEmpty(range(undefined, undefined)); - assert.isEmpty(range(NaN, NaN, NaN)); - assert.isEmpty(range(undefined, undefined, undefined)); - assert.isEmpty(range(0, 10, NaN)); - assert.isEmpty(range(10, 0, NaN)); - assert.isEmpty(range(0, 10, undefined)); - assert.isEmpty(range(10, 0, undefined)); - }, - "returns an empty range if start equals stop": function(range) { - assert.isEmpty(range(10, 10)); - assert.isEmpty(range(10, 10, 1)); - assert.isEmpty(range(10, 10, -1)); - assert.isEmpty(range(10, 10, -.5)); - assert.isEmpty(range(10, 10, .5)); - assert.isEmpty(range(0, 0)); - assert.isEmpty(range(0, 0, 1)); - assert.isEmpty(range(0, 0, -1)); - assert.isEmpty(range(0, 0, -.5)); - assert.isEmpty(range(0, 0, .5)); - }, - "returns an empty range if stop is less than start and step is positive": function(range) { - assert.isEmpty(range(20, 10)); - assert.isEmpty(range(20, 10, 2)); - assert.isEmpty(range(20, 10, 1)); - assert.isEmpty(range(20, 10, .5)); - }, - "returns an empty range if stop is greater than start and step is negative": function(range) { - assert.isEmpty(range(10, 20, -2)); - assert.isEmpty(range(10, 20, -1)); - assert.isEmpty(range(10, 20, -.5)); - } - } -}); - -suite.export(module); diff --git a/test/arrays/set-test.js b/test/arrays/set-test.js deleted file mode 100644 index 726d428f7edad2..00000000000000 --- a/test/arrays/set-test.js +++ /dev/null @@ -1,136 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("assert"); - -var suite = vows.describe("d3.set"); - -suite.addBatch({ - "set": { - topic: load("arrays/set").expression("d3.set"), - "constructor": { - "set() returns an empty set": function(set) { - var s = set(); - assert.deepEqual(s.values(), []); - }, - "set(null) returns an empty set": function(set) { - var s = set(null); - assert.deepEqual(s.values(), []); - }, - "set(array) adds array entries": function(set) { - var s = set(["foo"]); - assert.isTrue(s.has("foo")); - var s = set(["foo", "bar"]); - assert.isTrue(s.has("foo")); - assert.isTrue(s.has("bar")); - } - }, - "forEach": { - "empty sets have an empty values array": function(set) { - var s = set(); - assert.deepEqual(s.values(), []); - s.add("foo"); - assert.deepEqual(s.values(), ["foo"]); - s.remove("foo"); - assert.deepEqual(s.values(), []); - }, - "values are returned in arbitrary order": function(set) { - var s = set(["foo", "bar"]); - assert.deepEqual(s.values().sort(_.ascending), ["bar", "foo"]); - var s = set(["bar", "foo"]); - assert.deepEqual(s.values().sort(_.ascending), ["bar", "foo"]); - }, - "observes changes via add and remove": function(set) { - var s = set(["foo", "bar"]); - assert.deepEqual(s.values().sort(_.ascending), ["bar", "foo"]); - s.remove("foo"); - assert.deepEqual(s.values(), ["bar"]); - s.add("bar"); - assert.deepEqual(s.values(), ["bar"]); - s.add("foo"); - assert.deepEqual(s.values().sort(_.ascending), ["bar", "foo"]); - s.remove("bar"); - assert.deepEqual(s.values(), ["foo"]); - s.remove("foo"); - assert.deepEqual(s.values(), []); - s.remove("foo"); - assert.deepEqual(s.values(), []); - } - }, - "values": { - "returns an array of string values": function(set) { - var s = set(["foo", "bar"]); - assert.deepEqual(s.values().sort(), ["bar", "foo"]); - } - }, - "has": { - "empty sets do not have object built-ins": function(set) { - var s = set(); - assert.isFalse(s.has("__proto__")); - assert.isFalse(s.has("hasOwnProperty")); - }, - "coerces values to strings": function(set) { - var s = set(["42", "null", "undefined"]); - assert.isTrue(s.has(42)); - assert.isTrue(s.has(null)); - assert.isTrue(s.has(undefined)); - }, - "observes changes via add and remove": function(set) { - var s = set(["foo"]); - assert.isTrue(s.has("foo")); - s.add("foo"); - assert.isTrue(s.has("foo")); - s.remove("foo"); - assert.isFalse(s.has("foo")); - s.add("foo"); - assert.isTrue(s.has("foo")); - }, - "returns undefined for missing values": function(set) { - var s = set(["foo"]); - assert.isFalse(s.has("bar")); - } - }, - "add": { - "returns the set value": function(set) { - var s = set(); - assert.equal(s.add("foo"), "foo"); - }, - "can add values using built-in names": function(set) { - var s = set(); - s.add("__proto__"); - assert.isTrue(s.has("__proto__")); - }, - "coerces values to strings": function(set) { - var s = set(); - s.add(42); - assert.isTrue(s.has(42)); - s.add(null); - assert.isTrue(s.has(null)); - s.add(undefined); - assert.isTrue(s.has(undefined)); - assert.deepEqual(s.values().sort(), ["42", "null", "undefined"]); - }, - "can add null, undefined or empty string values": function(set) { - var s = set(); - s.add(""); - s.add("null"); - s.add("undefined"); - assert.isTrue(s.has("")); - assert.isTrue(s.has("null")); - assert.isTrue(s.has("undefined")); - } - }, - "remove": { - "returns true if the value was removed": function(set) { - var s = set(["foo"]); - assert.isTrue(s.remove("foo")); - }, - "returns false if the value is not an element": function(set) { - var s = set(); - assert.isFalse(s.remove("foo")); - } - } - } -}); - -suite.export(module); diff --git a/test/arrays/sum-test.js b/test/arrays/sum-test.js deleted file mode 100644 index 81a3a9c76f6934..00000000000000 --- a/test/arrays/sum-test.js +++ /dev/null @@ -1,43 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.sum"); - -suite.addBatch({ - "sum": { - topic: load("arrays/sum").expression("d3.sum"), - "sums numbers": function(sum) { - assert.equal(sum([1]), 1); - assert.equal(sum([5, 1, 2, 3, 4]), 15); - assert.equal(sum([20, 3]), 23); - assert.equal(sum([3, 20]), 23); - }, - "sums types that can be coerced to numbers": function(sum) { - assert.equal(sum(["20", "3"]), 23); - assert.equal(sum(["3", "20"]), 23); - assert.equal(sum(["3", 20]), 23); - assert.equal(sum([20, "3"]), 23); - assert.equal(sum([3, "20"]), 23); - assert.equal(sum(["20", 3]), 23); - }, - "ignores non-numeric types": function(sum) { - assert.equal(sum(["a", "b", "c"]), 0); - assert.equal(sum(["a", 1, "2"]), 3); - }, - "ignores null, undefined and NaN": function(sum) { - assert.equal(sum([NaN, 1, 2, 3, 4, 5]), 15); - assert.equal(sum([1, 2, 3, 4, 5, NaN]), 15); - assert.equal(sum([10, null, 3, undefined, 5, NaN]), 18); - }, - "applies the optional acccessor function": function(sum) { - assert.equal(sum([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return sum(d); }), 45); - assert.equal(sum([1, 2, 3, 4, 5], function(d, i) { return i; }), 10); - }, - "returns zero for the empty array": function(sum) { - assert.equal(sum([]), 0); - } - } -}); - -suite.export(module); diff --git a/test/arrays/transpose-test.js b/test/arrays/transpose-test.js deleted file mode 100644 index 84b6b55ded98c3..00000000000000 --- a/test/arrays/transpose-test.js +++ /dev/null @@ -1,28 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.transpose"); - -suite.addBatch({ - "transpose": { - topic: load("arrays/transpose").expression("d3.transpose"), - "transposes a square matrix": function(transpose) { - assert.deepEqual(transpose([[1, 2], [3, 4]]), [[1, 3], [2, 4]]); - }, - "transposes a non-square matrix": function(transpose) { - assert.deepEqual(transpose([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]]), [[1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]); - }, - "transposes a single-row matrix": function(transpose) { - assert.deepEqual(transpose([[1, 2, 3, 4, 5]]), [[1], [2], [3], [4], [5]]); - }, - "transposes an empty matrix": function(transpose) { - assert.deepEqual(transpose([]), []); - }, - "ignores extra elements given an irregular matrix": function(transpose) { - assert.deepEqual(transpose([[1, 2], [3, 4], [5, 6, 7]]), [[1, 3, 5], [2, 4, 6]]); - } - } -}); - -suite.export(module); diff --git a/test/arrays/values-test.js b/test/arrays/values-test.js deleted file mode 100644 index f244deedb6e837..00000000000000 --- a/test/arrays/values-test.js +++ /dev/null @@ -1,31 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.values"); - -suite.addBatch({ - "values": { - topic: load("arrays/values").expression("d3.values"), - "enumerates every value": function(values) { - assert.deepEqual(values({a: 1, b: 2}), [1, 2]); - }, - "includes values defined on prototypes": function(values) { - function abc() { - this.a = 1; - this.b = 2; - } - abc.prototype.c = 3; - assert.deepEqual(values(new abc()), [1, 2, 3]); - }, - "includes null or undefined values": function(values) { - var v = values({a: undefined, b: null, c: NaN}); - assert.isUndefined(v[0]); - assert.isNull(v[1]); - assert.isNaN(v[2]); - assert.equal(v.length, 3); - } - } -}); - -suite.export(module); diff --git a/test/arrays/zip-test.js b/test/arrays/zip-test.js deleted file mode 100644 index 56b40766291a49..00000000000000 --- a/test/arrays/zip-test.js +++ /dev/null @@ -1,28 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.zip"); - -suite.addBatch({ - "zip": { - topic: load("arrays/zip").expression("d3.zip"), - "transposes a square matrix": function(zip) { - assert.deepEqual(zip([1, 2], [3, 4]), [[1, 3], [2, 4]]); - }, - "transposes a non-square matrix": function(zip) { - assert.deepEqual(zip([1, 2, 3, 4, 5], [2, 4, 6, 8, 10]), [[1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]); - }, - "transposes a single-row matrix": function(zip) { - assert.deepEqual(zip([1, 2, 3, 4, 5]), [[1], [2], [3], [4], [5]]); - }, - "transposes an empty matrix": function(zip) { - assert.deepEqual(zip(), []); - }, - "ignores extra elements given an irregular matrix": function(zip) { - assert.deepEqual(zip([1, 2], [3, 4], [5, 6, 7]), [[1, 3, 5], [2, 4, 6]]); - } - } -}); - -suite.export(module); diff --git a/test/assert.js b/test/assert.js deleted file mode 100644 index 3acac5163f946f..00000000000000 --- a/test/assert.js +++ /dev/null @@ -1,153 +0,0 @@ -var assert = require("assert"), - _ = require("../"); - -assert = module.exports = Object.create(assert); - -assert.isArray = function(actual, message) { - if (!Array.isArray(actual)) { - assert.fail(actual, null, message || "expected {actual} to be an Array", null, assert.isArray); - } -}; - -assert.inDelta = function(actual, expected, delta, message) { - if (!inDelta(actual, expected, delta)) { - assert.fail(actual, expected, message || "expected {actual} to be in within *" + delta + "* of {expected}", null, assert.inDelta); - } -}; - -assert.domNull = function(actual, message) { - if (actual != null) { - assert.fail(actual+"", null, message || "expected null, got {actual}", "===", assert.domNull); - } -}; - -assert.domEqual = function(actual, expected, message) { - if (actual !== expected) { - assert.fail(actual+"", expected+"", message || "expected {expected}, got {actual}", "===", assert.domEqual); - } -}; - -assert.rgbEqual = function(actual, r, g, b, message) { - var ar = Math.round(actual.r), - ag = Math.round(actual.g), - ab = Math.round(actual.b), - er = Math.round(r), - eg = Math.round(g), - eb = Math.round(b); - if (ar !== er || ag !== eg || ab !== eb) { - assert.fail( - "rgb(" + ar + "," + ag + "," + ab + ")", - "rgb(" + er + ", " + eg + ", " + eb + ")", - message || "expected {expected}, got {actual}", "===", assert.rgbEqual); - } -}; - -assert.hslEqual = function(actual, h, s, l, message) { - var ah = _.round(actual.h, 2), - as = _.round(actual.s, 2), - al = _.round(actual.l, 2), - eh = _.round(h, 2), - es = _.round(s, 2), - el = _.round(l, 2); - if ((!(isNaN(ah) && isNaN(eh)) && ah !== eh) || (!(isNaN(as) && isNaN(es)) && as !== es) || al !== el) { - assert.fail( - "hsl(" + ah + "," + as + "," + al + ")", - "hsl(" + eh + "," + es + "," + el + ")", - message || "expected {expected}, got {actual}", null, assert.hslEqual); - } -}; - -assert.hclEqual = function(actual, h, c, l, message) { - var ah = _.round(actual.h, 2), - ac = _.round(actual.c, 2), - al = _.round(actual.l, 2), - eh = _.round(h, 2), - ec = _.round(c, 2), - el = _.round(l, 2); - if ((!(isNaN(ah) && isNaN(eh)) && ah !== eh) || ac !== ec || al !== el) { - assert.fail( - "hcl(" + ah + "," + ac + "," + al + ")", - "hcl(" + eh + "," + ec + "," + el + ")", - message || "expected {expected}, got {actual}", null, assert.hclEqual); - } -}; - -assert.labEqual = function(actual, l, a, b, message) { - var al = _.round(actual.l, 2), - aa = _.round(actual.a, 2), - ab = _.round(actual.b, 2), - el = _.round(l, 2), - ea = _.round(a, 2), - eb = _.round(b, 2); - if (al !== el || aa !== ea || ab !== eb) { - assert.fail( - "lab(" + al + ", " + aa + ", " + ab + ")", - "lab(" + el + ", " + ea + ", " + eb + ")", - message || "expected {expected}, got {actual}", null, assert.labEqual); - } -}; - -assert.pathEqual = function(actual, expected, message) { - if (!pathEqual(actual, expected)) { - assert.fail(formatPath(actual), formatPath(expected), message || "expected {expected}, got {actual}", null, assert.pathEqual); - } -}; - -function inDelta(actual, expected, delta) { - return (Array.isArray(expected) ? inDeltaArray : inDeltaNumber)(actual, expected, delta); -} - -function inDeltaArray(actual, expected, delta) { - var n = expected.length, i = -1; - if (actual.length !== n) return false; - while (++i < n) if (!inDelta(actual[i], expected[i], delta)) return false; - return true; -} - -function inDeltaNumber(actual, expected, delta) { - return actual >= expected - delta && actual <= expected + delta; -} - -function pathEqual(a, b) { - a = parsePath(a); - b = parsePath(b); - var n = a.length, i = -1, x, y; - if (n !== b.length) return false; - while (++i < n) { - x = a[i]; - y = b[i]; - if (typeof x === "string") { - if (x !== y) return false; - } else if (typeof y !== "number") { - return false; - } else if (Math.abs(x - y) > 1e-6) { - return false; - } - } - return true; -} - -var reNumber = /[-+]?(?:\d+\.\d+|\d+\.|\.\d+|\d+)(?:[eE][-]?\d+)?/g; - -function parsePath(path) { - var parts = []; - reNumber.lastIndex = 0; - for (var i = 0, s0 = 0, s1, m; m = reNumber.exec(path); ++i) { - if (m.index) { - var part = path.substring(s0, s1 = m.index); - if (!/^[, ]$/.test(part)) parts.push(part); - } - parts.push(parseFloat(m[0])); - s0 = reNumber.lastIndex; - } - if (s0 < path.length) parts.push(path.substring(s0)); - return parts; -} - -function formatPath(path) { - return path.replace(reNumber, formatNumber); -} - -function formatNumber(s) { - return Math.abs((s = +s) - Math.floor(s)) < 1e-6 ? Math.floor(s) : s.toFixed(6); -} diff --git a/test/color/hcl-test.js b/test/color/hcl-test.js deleted file mode 100644 index cb5db71adb3578..00000000000000 --- a/test/color/hcl-test.js +++ /dev/null @@ -1,112 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.hcl"); - -suite.addBatch({ - "hcl": { - topic: load("color/hcl").expression("d3.hcl"), - "converts string channel values to numbers": function(hcl) { - assert.hclEqual(hcl("50", "-4", "32"), 50, -4, 32); - }, - "converts null channel values to zero": function(hcl) { - assert.hclEqual(hcl(null, null, null), 0, 0, 0); - }, - "exposes h, c and l properties": function(hcl) { - var color = hcl(50, -4, 32); - assert.equal(color.h, 50); - assert.equal(color.c, -4); - assert.equal(color.l, 32); - }, - "changing h, c or l affects the string format": function(hcl) { - var color = hcl(50, -4, 32); - assert.equal(color + "", "#444d50"); - color.h++; - assert.equal(color + "", "#444d50"); - color.c++; - assert.equal(color + "", "#464c4f"); - color.l++; - assert.equal(color + "", "#494f51"); - }, - "parses hexadecimal shorthand format (e.g., \"#abc\")": function(hcl) { - assert.hclEqual(hcl("#abc"), -102.28223831811077, 10.774886733325554, 75.10497524893663); - }, - "parses hexadecimal format (e.g., \"#abcdef\")": function(hcl) { - assert.hclEqual(hcl("#abcdef"), -100.15785184209284, 20.768234621934273, 81.04386565274363); - }, - "parses HSL format (e.g., \"hsl(210, 64%, 13%)\")": function(hcl) { - assert.hclEqual(hcl("hsl(210, 64.7058%, 13.33333%)"), -89.58282792342067, 16.833655998102003, 12.65624852526134); - }, - "parses color names (e.g., \"moccasin\")": function(hcl) { - assert.hclEqual(hcl("moccasin"), 84.71288921124494, 26.472460854104156, 91.72317744746022); - }, - "parses and converts RGB format (e.g., \"rgb(102, 102, 0)\")": function(hcl) { - assert.hclEqual(hcl("rgb(102, 102, 0)"), 102.85124420310271, 49.44871600399321, 41.73251953866431); - }, - "can convert from RGB": function(hcl) { - assert.hclEqual(hcl(_.rgb(12, 34, 56)), -89.58282792342067, 16.833655998102003, 12.65624852526134); - }, - "can convert from HSL": function(hcl) { - assert.hclEqual(hcl(hcl(20, .8, .3)), 20, 0.8, 0.3); - }, - "can convert to RGB": function(hcl) { - assert.rgbEqual(hcl("steelblue").rgb(), 70, 130, 180); - }, - "can derive a brighter color": function(hcl) { - assert.hclEqual(hcl("steelblue").brighter(), -97.21873224090723, 32.44906314974561, 70.46551718768575); - assert.hclEqual(hcl("steelblue").brighter(.5), -97.21873224090723, 32.44906314974561, 61.46551718768575); - }, - "can derive a darker color": function(hcl) { - assert.hclEqual(hcl("lightsteelblue").darker(), -94.8160116310511, 15.26488988314746, 60.45157936968134); - assert.hclEqual(hcl("lightsteelblue").darker(.5), -94.8160116310511, 15.26488988314746, 69.45157936968134); - }, - "string coercion returns RGB format": function(hcl) { - assert.strictEqual(hcl("hsl(60, 100%, 20%)") + "", "#666600"); - assert.strictEqual(hcl(hcl(60, -4, 32)) + "", "#454c51"); - }, - "roundtrip to HSL is idempotent": function(hcl) { - assert.deepEqual(_.hsl(hcl("steelblue")), _.hsl("steelblue")); - }, - "roundtrip to RGB is idempotent": function(hcl) { - assert.deepEqual(_.rgb(hcl("steelblue")), _.rgb("steelblue")); - }, - "roundtrip to Lab is idempotent": function(hcl) { - assert.deepEqual(_.lab(hcl("steelblue")), _.lab("steelblue")); - }, - "h is defined for non-black grayscale colors (because of the color profile)": function(hcl) { - assert.inDelta(hcl("#ccc").h, 158.1986, 1e-3); - assert.inDelta(hcl("gray").h, 158.1986, 1e-3); - assert.inDelta(hcl(_.rgb("gray")).h, 158.1986, 1e-3); - assert.inDelta(hcl("#fff").h, 158.1986, 1e-3); - assert.inDelta(hcl("white").h, 158.1986, 1e-3); - assert.inDelta(hcl(_.rgb("white")).h, 158.1986, 1e-3); - }, - "h is preserved when explicitly specified, even for black": function(hcl) { - assert.strictEqual(hcl(0, 0, 0).h, 0); - assert.strictEqual(hcl(42, 0, 0).h, 42); - assert.strictEqual(hcl(118, 0, 0).h, 118); - }, - "h is undefined when not explicitly specified for black": function(hcl) { - assert.isNaN(hcl("#000").h); - assert.isNaN(hcl("black").h); - assert.isNaN(hcl(_.rgb("black")).h); - }, - "c is preserved when explicitly specified, even for black": function(hcl) { - assert.strictEqual(hcl(0, 0, 0).c, 0); - assert.strictEqual(hcl(0, .42, 0).c, .42); - assert.strictEqual(hcl(0, 1, 0).c, 1); - }, - "c is undefined when not explicitly specified for black": function(hcl) { - assert.isNaN(hcl("#000").c); - assert.isNaN(hcl("black").c); - assert.isNaN(hcl(_.rgb("black")).c); - }, - "can convert black (with undefined hue and chroma) to RGB": function(hcl) { - assert.strictEqual(hcl(NaN, NaN, 0) + "", "#000000"); - } - } -}); - -suite.export(module); diff --git a/test/color/hsl-test.js b/test/color/hsl-test.js deleted file mode 100644 index 44fa2d16be0560..00000000000000 --- a/test/color/hsl-test.js +++ /dev/null @@ -1,118 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.hsl"); - -suite.addBatch({ - "hsl": { - topic: load("color/hsl").expression("d3.hsl"), - "does not clamp channel values": function(hsl) { - assert.hslEqual(hsl(-100, -1, -2), -100, -1, -2); - assert.hslEqual(hsl(400, 2, 3), 400, 2, 3); - }, - "converts string channel values to numbers": function(hsl) { - assert.hslEqual(hsl("180", ".5", ".6"), 180, .5, .6); - }, - "converts null channel values to zero": function(hsl) { - assert.hslEqual(hsl(null, null, null), 0, 0, 0); - }, - "exposes h, s and l properties": function(hsl) { - assert.hslEqual(hsl("hsl(180, 50%, 60%)"), 180, .5, .6); - }, - "changing h, s or l affects the string format": function(hsl) { - var color = hsl("hsl(180, 50%, 60%)"); - color.h++; - color.s += .1; - color.l += .1; - assert.equal(color + "", "#85dfe0"); - }, - "parses hexadecimal shorthand format (e.g., \"#abc\")": function(hsl) { - assert.hslEqual(hsl("#abc"), 210, .25, .733333); - }, - "parses hexadecimal format (e.g., \"#abcdef\")": function(hsl) { - assert.hslEqual(hsl("#abcdef"), 210, .68, .803922); - }, - "parses HSL format (e.g., \"hsl(210, 64%, 13%)\")": function(hsl) { - assert.hslEqual(hsl("hsl(210, 64.7058%, 13.33333%)"), 210, .647058, .133333); - }, - "parses color names (e.g., \"moccasin\")": function(hsl) { - assert.hslEqual(hsl("moccasin"), 38.108108, 1, .854902); - assert.hslEqual(hsl("aliceblue"), 208, 1, .970588); - assert.hslEqual(hsl("yellow"), 60, 1, .5); - }, - "parses and converts RGB format (e.g., \"rgb(102, 102, 0)\")": function(hsl) { - assert.hslEqual(hsl("rgb(102, 102, 0)"), 60, 1, .2); - }, - "can convert from RGB": function(hsl) { - assert.hslEqual(hsl(_.rgb(12, 34, 56)), 210, .647058, .133333); - }, - "can convert from HSL": function(hsl) { - assert.hslEqual(hsl(hsl(20, .8, .3)), 20, .8, .3); - }, - "can convert to RGB": function(hsl) { - assert.rgbEqual(hsl("steelblue").rgb(), 70, 130, 180); - }, - "can derive a brighter color": function(hsl) { - assert.hslEqual(hsl("steelblue").brighter(), 207.272727, .44, .7002801); - assert.hslEqual(hsl("steelblue").brighter(.5), 207.272727, .44, .5858964); - assert.hslEqual(hsl("steelblue").brighter(1), 207.272727, .44, .7002801); - assert.hslEqual(hsl("steelblue").brighter(2), 207.272727, .44, 1.0004002); - }, - "can derive a darker color": function(hsl) { - assert.hslEqual(hsl("lightsteelblue").darker(), 213.913043, .4107143, .5462745); - assert.hslEqual(hsl("lightsteelblue").darker(.5), 213.913043, .4107143, .6529229); - assert.hslEqual(hsl("lightsteelblue").darker(1), 213.913043, .4107143, .5462745); - assert.hslEqual(hsl("lightsteelblue").darker(2), 213.913043, .4107143, .38239216); - }, - "string coercion returns RGB format": function(hsl) { - assert.strictEqual(hsl("hsl(60, 100%, 20%)") + "", "#666600"); - assert.strictEqual(hsl(hsl(60, 1, .2)) + "", "#666600"); - }, - "h is preserved when explicitly specified, even for grayscale colors": function(hsl) { - assert.hslEqual(hsl(0, 0, 0), 0, 0, 0); - assert.hslEqual(hsl(42, 0, .5), 42, 0, .5); - assert.hslEqual(hsl(118, 0, 1), 118, 0, 1); - }, - "h is undefined when not explicitly specified for grayscale colors": function(hsl) { - assert.hslEqual(hsl("#000"), NaN, NaN, 0); - assert.hslEqual(hsl("black"), NaN, NaN, 0); - assert.hslEqual(hsl(_.rgb("black")), NaN, NaN, 0); - assert.hslEqual(hsl("#ccc"), NaN, 0, .8); - assert.hslEqual(hsl("gray"), NaN, 0, .5); - assert.hslEqual(hsl(_.rgb("gray")), NaN, 0, .5); - assert.hslEqual(hsl("#fff"), NaN, NaN, 1); - assert.hslEqual(hsl("white"), NaN, NaN, 1); - assert.hslEqual(hsl(_.rgb("white")), NaN, NaN, 1); - }, - "s is preserved when explicitly specified, even for white or black": function(hsl) { - assert.hslEqual(hsl(0, 0, 0), 0, 0, 0); - assert.hslEqual(hsl(0, .18, 0), 0, .18, 0); - assert.hslEqual(hsl(0, .42, 1), 0, .42, 1); - assert.hslEqual(hsl(0, 1, 1), 0, 1, 1); - }, - "s is zero for grayscale colors (but not white and black)": function(hsl) { - assert.hslEqual(hsl("#ccc"), NaN, 0, .8); - assert.hslEqual(hsl("#777"), NaN, 0, .47); - }, - "s is undefined when not explicitly specified for white or black": function(hsl) { - assert.hslEqual(hsl("#000"), NaN, NaN, 0); - assert.hslEqual(hsl("black"), NaN, NaN, 0); - assert.hslEqual(hsl(_.rgb("black")), NaN, NaN, 0); - assert.hslEqual(hsl("#fff"), NaN, NaN, 1); - assert.hslEqual(hsl("white"), NaN, NaN, 1); - assert.hslEqual(hsl(_.rgb("white")), NaN, NaN, 1); - }, - "can convert grayscale colors (with undefined hue) to RGB": function(hsl) { - assert.strictEqual(hsl(NaN, 0, .2) + "", "#333333"); - assert.strictEqual(hsl(NaN, 0, .6) + "", "#999999"); - }, - "can convert white and black (with undefined hue and saturation) to RGB": function(hsl) { - assert.strictEqual(hsl(NaN, NaN, 0) + "", "#000000"); - assert.strictEqual(hsl(NaN, NaN, 1) + "", "#ffffff"); - } - } -}); - -suite.export(module); diff --git a/test/color/lab-test.js b/test/color/lab-test.js deleted file mode 100644 index d8a3f6c3038fd5..00000000000000 --- a/test/color/lab-test.js +++ /dev/null @@ -1,81 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.lab"); - -suite.addBatch({ - "lab": { - topic: load("color/lab").expression("d3.lab"), - "converts string channel values to numbers": function(lab) { - assert.labEqual(lab("50", "-4", "-32"), 50, -4, -32); - }, - "converts null channel values to zero": function(lab) { - assert.labEqual(lab(null, null, null), 0, 0, 0); - }, - "exposes l, a and b properties": function(lab) { - var color = lab(50, -4, -32); - assert.equal(color.l, 50); - assert.equal(color.a, -4); - assert.equal(color.b, -32); - }, - "changing l, a or b affects the string format": function(lab) { - var color = lab(50, -4, -32); - assert.equal(color + "", "#3f7cad"); - color.l++; - assert.equal(color + "", "#427eb0"); - color.a++; - assert.equal(color + "", "#467eb0"); - color.b++; - assert.equal(color + "", "#487eae"); - }, - "parses hexadecimal shorthand format (e.g., \"#abc\")": function(lab) { - assert.labEqual(lab("#abc"), 75.10497524893663, -2.292114632248876, -10.528266458853786); - }, - "parses hexadecimal format (e.g., \"#abcdef\")": function(lab) { - assert.labEqual(lab("#abcdef"), 81.04386565274363, -3.6627002800885267, -20.442705201854984); - }, - "parses HSL format (e.g., \"hsl(210, 64%, 13%)\")": function(lab) { - assert.labEqual(lab("hsl(210, 64.7058%, 13.33333%)"), 12.65624852526134, 0.12256520883417721, -16.833209795877284); - }, - "parses color names (e.g., \"moccasin\")": function(lab) { - assert.labEqual(lab("moccasin"), 91.72317744746022, 2.4393469358685027, 26.359832514614844); - }, - "parses and converts RGB format (e.g., \"rgb(102, 102, 0)\")": function(lab) { - assert.labEqual(lab("rgb(102, 102, 0)"), 41.73251953866431, -10.998411255098816, 48.21006600604577); - }, - "can convert from RGB": function(lab) { - assert.labEqual(lab(_.rgb(12, 34, 56)), 12.65624852526134, 0.12256520883417721, -16.833209795877284); - }, - "can convert from HSL": function(lab) { - assert.labEqual(lab(lab(20, .8, .3)), 20, 0.8, 0.3); - }, - "can convert to RGB": function(lab) { - assert.rgbEqual(lab("steelblue").rgb(), 70, 130, 180); - }, - "can derive a brighter color": function(lab) { - assert.labEqual(lab("steelblue").brighter(), 70.46551718768575, -4.0774710123572255, -32.19186122981343); - assert.labEqual(lab("steelblue").brighter(.5), 61.46551718768575, -4.0774710123572255, -32.19186122981343); - }, - "can derive a darker color": function(lab) { - assert.labEqual(lab("lightsteelblue").darker(), 60.45157936968134, -1.2815839134120433, -15.210996213841522); - assert.labEqual(lab("lightsteelblue").darker(.5), 69.45157936968134, -1.2815839134120433, -15.210996213841522); - }, - "string coercion returns RGB format": function(lab) { - assert.strictEqual(lab("hsl(60, 100%, 20%)") + "", "#666600"); - assert.strictEqual(lab(lab(60, -4, -32)) + "", "#5d95c8"); - }, - "roundtrip to HSL is idempotent": function(lab) { - assert.deepEqual(_.hsl(lab("steelblue")), _.hsl("steelblue")); - }, - "roundtrip to RGB is idempotent": function(lab) { - assert.deepEqual(_.rgb(lab("steelblue")), _.rgb("steelblue")); - }, - "roundtrip to HCL is idempotent": function(lab) { - assert.deepEqual(_.hcl(lab("steelblue")), _.hcl("steelblue")); - } - } -}); - -suite.export(module); diff --git a/test/color/rgb-test.js b/test/color/rgb-test.js deleted file mode 100644 index 6daf648b43783d..00000000000000 --- a/test/color/rgb-test.js +++ /dev/null @@ -1,91 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.rgb"); - -suite.addBatch({ - "rgb": { - topic: load("color/rgb").expression("d3.rgb"), - "floors channel values": function(rgb) { - assert.rgbEqual(rgb(1.2, 2.6, 42.9), 1, 2, 42); - }, - "defaults to black for invalid inputs": function(rgb) { - assert.rgbEqual(rgb("invalid"), 0, 0, 0); - assert.rgbEqual(rgb("hasOwnProperty"), 0, 0, 0); - assert.rgbEqual(rgb("__proto__"), 0, 0, 0); - }, - "does not clamp channel values": function(rgb) { - assert.rgbEqual(rgb(-10, -20, -30), -10, -20, -30); - assert.rgbEqual(rgb(300, 400, 500), 300, 400, 500); - }, - "converts string channel values to numbers": function(rgb) { - assert.rgbEqual(rgb("12", "34", "56"), 12, 34, 56); - }, - "converts null channel values to zero": function(rgb) { - assert.rgbEqual(rgb(null, null, null), 0, 0, 0); - }, - "exposes r, g and b properties": function(rgb) { - var color = rgb("#abc"); - assert.equal(color.r, 170); - assert.equal(color.g, 187); - assert.equal(color.b, 204); - }, - "changing r, g or b affects the string format": function(rgb) { - var color = rgb("#abc"); - color.r++; - color.g++; - color.b++; - assert.equal(color + "", "#abbccd"); - }, - "parses hexadecimal shorthand format (e.g., \"#abc\")": function(rgb) { - assert.rgbEqual(rgb("#abc"), 170, 187, 204); - }, - "parses hexadecimal format (e.g., \"#abcdef\")": function(rgb) { - assert.rgbEqual(rgb("#abcdef"), 171, 205, 239); - }, - "parses RGB format (e.g., \"rgb(12, 34, 56)\")": function(rgb) { - assert.rgbEqual(rgb("rgb(12, 34, 56)"), 12, 34, 56); - }, - "parses color names (e.g., \"moccasin\")": function(rgb) { - assert.rgbEqual(rgb("moccasin"), 255, 228, 181); - assert.rgbEqual(rgb("aliceblue"), 240, 248, 255); - assert.rgbEqual(rgb("yellow"), 255, 255, 0); - }, - "parses and converts HSL format (e.g., \"hsl(60, 100%, 20%)\")": function(rgb) { - assert.rgbEqual(rgb("hsl(60, 100%, 20%)"), 102, 102, 0); - }, - "can convert from RGB": function(rgb) { - assert.rgbEqual(rgb(rgb(12, 34, 56)), 12, 34, 56); - }, - "can convert from HSL": function(rgb) { - assert.rgbEqual(rgb(_.hsl(0, 1, .5)), 255, 0, 0); - }, - "can convert to HSL": function(rgb) { - assert.hslEqual(rgb("red").hsl(), 0, 1, .5); - }, - "can derive a brighter color": function(rgb) { - assert.rgbEqual(rgb("brown").brighter(), 235, 60, 60); - assert.rgbEqual(rgb("brown").brighter(.5), 197, 50, 50); - assert.rgbEqual(rgb("brown").brighter(1), 235, 60, 60); - assert.rgbEqual(rgb("brown").brighter(2), 255, 85, 85); - }, - "can derive a darker color": function(rgb) { - assert.rgbEqual(rgb("coral").darker(), 178, 88, 56); - assert.rgbEqual(rgb("coral").darker(.5), 213, 106, 66); - assert.rgbEqual(rgb("coral").darker(1), 178, 88, 56); - assert.rgbEqual(rgb("coral").darker(2), 124, 62, 39); - }, - "string coercion returns hexadecimal format": function(rgb) { - assert.strictEqual(rgb("#abcdef") + "", "#abcdef"); - assert.strictEqual(rgb("moccasin") + "", "#ffe4b5"); - assert.strictEqual(rgb("hsl(60, 100%, 20%)") + "", "#666600"); - assert.strictEqual(rgb("rgb(12, 34, 56)") + "", "#0c2238"); - assert.strictEqual(rgb(rgb(12, 34, 56)) + "", "#0c2238"); - assert.strictEqual(rgb(_.hsl(60, 1, .2)) + "", "#666600"); - } - } -}); - -suite.export(module); diff --git a/test/core/functor-test.js b/test/core/functor-test.js deleted file mode 100644 index ef88473c8aec1f..00000000000000 --- a/test/core/functor-test.js +++ /dev/null @@ -1,25 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.functor"); - -suite.addBatch({ - "functor": { - topic: load("core/functor").expression("d3.functor"), - "when passed a function, returns the function": function(functor) { - function foo() {} - assert.strictEqual(functor(foo), foo); - }, - "when passed a non-function, returns a wrapper function": function(functor) { - var a = {}; - assert.isNull(functor(null)()); - assert.isUndefined(functor(undefined)()); - assert.strictEqual(functor(a)(), a); - assert.strictEqual(functor(1)(), 1); - assert.deepEqual(functor([1])(), [1]); - } - } -}); - -suite.export(module); diff --git a/test/core/ns-test.js b/test/core/ns-test.js deleted file mode 100644 index 3506dc14954bd5..00000000000000 --- a/test/core/ns-test.js +++ /dev/null @@ -1,57 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("ns"); - -suite.addBatch({ - "ns": { - topic: load("core/ns").expression("d3.ns"), - "prefix": { - topic: function(ns) { - return ns.prefix; - }, - "svg is http://www.w3.org/2000/svg": function(prefix) { - assert.equal(prefix.svg, "http://www.w3.org/2000/svg"); - }, - "xhtml is http://www.w3.org/1999/xhtml": function(prefix) { - assert.equal(prefix.xhtml, "http://www.w3.org/1999/xhtml"); - }, - "xlink is http://www.w3.org/1999/xlink": function(prefix) { - assert.equal(prefix.xlink, "http://www.w3.org/1999/xlink"); - }, - "xml is http://www.w3.org/XML/1998/namespace": function(prefix) { - assert.equal(prefix.xml, "http://www.w3.org/XML/1998/namespace"); - }, - "xmlns is http://www.w3.org/2000/xmlns/": function(prefix) { - assert.equal(prefix.xmlns, "http://www.w3.org/2000/xmlns/"); - } - }, - "qualify": { - topic: function(ns) { - return ns.qualify; - }, - "local name returns name": function(qualify) { - assert.equal(qualify("local"), "local"); - }, - "known qualified name returns space and local": function(qualify) { - var name = qualify("svg:path"); - assert.equal(name.space, "http://www.w3.org/2000/svg"); - assert.equal(name.local, "path"); - }, - "unknown qualified name returns name": function(qualify) { - assert.equal(qualify("foo:bar"), "bar"); - }, - "known local name returns space and local": function(qualify) { - var name = qualify("svg"); - assert.equal(name.space, "http://www.w3.org/2000/svg"); - assert.equal(name.local, "svg"); - }, - "names that collide with built-ins are ignored": function(qualify) { - assert.equal(qualify("hasOwnProperty:test"), "test"); - } - } - } -}); - -suite.export(module); diff --git a/test/core/rebind-test.js b/test/core/rebind-test.js deleted file mode 100644 index 60a9bb6ab8b6d5..00000000000000 --- a/test/core/rebind-test.js +++ /dev/null @@ -1,50 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.rebind"); - -suite.addBatch({ - "rebind": { - topic: load("core/rebind").expression("d3.rebind"), - "source function always has source as context": function(rebind) { - var target = {}, source = {method: function() { that = this; }}, that; - rebind(target, source, "method"); - assert.strictEqual((target.method(), that), source); - assert.strictEqual((target.method.call({}), that), source); - }, - "source function receives target function's arguments": function(rebind) { - var target = {}, source = {method: function() { those = Array.prototype.slice.call(arguments); }}, those; - rebind(target, source, "method"); - assert.deepEqual((target.method(), those), []); - assert.deepEqual((target.method(1), those), [1]); - assert.deepEqual((target.method(null), those), [null]); - assert.deepEqual((target.method(source, source, 1), those), [source, source, 1]); - }, - "target function returns target if source function returns source": function(rebind) { - var target = {}, source = {method: function(value) { return value ? source : 42; }}; - rebind(target, source, "method"); - assert.strictEqual(target.method(true), target); - }, - "otherwise, target function returns source function return value": function(rebind) { - var target = {}, source = {method: function(value) { return value ? source : 42; }}; - rebind(target, source, "method"); - assert.strictEqual(target.method(false), 42); - }, - "can bind multiple methods": function(rebind) { - var target = {}, source = { - foo: function() { return 1; }, - bar: function() { return 2; } - }; - rebind(target, source, "foo", "bar"); - assert.strictEqual(target.foo(), 1); - assert.strictEqual(target.bar(), 2); - }, - "returns the target object": function(rebind) { - var target = {}, source = {foo: function() {}}; - assert.strictEqual(rebind(target, source, "foo"), target); - } - } -}); - -suite.export(module); diff --git a/test/core/version-test.js b/test/core/version-test.js deleted file mode 100644 index 23678d725a30f4..00000000000000 --- a/test/core/version-test.js +++ /dev/null @@ -1,16 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.version"); - -suite.addBatch({ - "version": { - topic: load().expression("d3.version"), - "has the form major.minor.patch": function(version) { - assert.match(version, /^[0-9]+\.[0-9]+\.[0-9]+/); - } - } -}); - -suite.export(module); diff --git a/test/d3-test.js b/test/d3-test.js new file mode 100644 index 00000000000000..7589e71db8f488 --- /dev/null +++ b/test/d3-test.js @@ -0,0 +1,12 @@ +var tape = require("tape-await"), + d3 = require("../"), + d3Selection = require("d3-selection"), + testExports = require("./test-exports"); + +tape("version matches package.json", function(test) { + test.equal(d3.version, require("../package.json").version); +}); + +for (var dependency in require("../package.json").dependencies) { + testExports(dependency); +} diff --git a/test/data/sample.csv b/test/data/sample.csv deleted file mode 100644 index 89d73a0fc0c3e2..00000000000000 --- a/test/data/sample.csv +++ /dev/null @@ -1,2 +0,0 @@ -Hello,World -42,"""fish""" diff --git a/test/data/sample.html b/test/data/sample.html deleted file mode 100644 index 2029283a42e964..00000000000000 --- a/test/data/sample.html +++ /dev/null @@ -1,5 +0,0 @@ - - - -

Hello & world!

- diff --git a/test/data/sample.json b/test/data/sample.json deleted file mode 100644 index 92c35fd7d66a63..00000000000000 --- a/test/data/sample.json +++ /dev/null @@ -1 +0,0 @@ -[{"Hello": 42, "World": "\"fish\""}] diff --git a/test/data/sample.tsv b/test/data/sample.tsv deleted file mode 100644 index 9998779de8a927..00000000000000 --- a/test/data/sample.tsv +++ /dev/null @@ -1,2 +0,0 @@ -Hello World -42 """fish""" diff --git a/test/data/sample.txt b/test/data/sample.txt deleted file mode 100644 index af5626b4a114ab..00000000000000 --- a/test/data/sample.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! diff --git a/test/data/sample.xml b/test/data/sample.xml deleted file mode 100644 index a2447a54cd0add..00000000000000 --- a/test/data/sample.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/test/data/us-counties.json b/test/data/us-counties.json deleted file mode 100644 index 2e0e3b6305fa10..00000000000000 --- a/test/data/us-counties.json +++ /dev/null @@ -1,3186 +0,0 @@ -{"type":"FeatureCollection","features":[ -{"type":"Feature","id":"01001","properties":{"name":"Autauga"},"geometry":{"type":"Polygon","coordinates":[[[-86.411786,32.706342],[-86.411786,32.410587],[-86.499417,32.344863],[-86.817079,32.339387],[-86.915664,32.662526],[-86.411786,32.706342]]]}}, -{"type":"Feature","id":"01003","properties":{"name":"Baldwin"},"geometry":{"type":"Polygon","coordinates":[[[-87.76459,31.298768],[-87.616713,31.243998],[-87.600282,30.997536],[-87.518128,30.280057],[-88.005575,30.685351],[-87.972714,31.161844],[-87.945329,31.194706],[-87.76459,31.298768]]]}}, -{"type":"Feature","id":"01005","properties":{"name":"Barbour"},"geometry":{"type":"Polygon","coordinates":[[[-85.354736,32.147694],[-85.053504,32.06554],[-85.069935,31.994339],[-85.141136,31.780739],[-85.124705,31.764308],[-85.414983,31.621907],[-85.694307,31.61643],[-85.749076,31.61643],[-85.655968,31.879324],[-85.409506,32.147694],[-85.354736,32.147694]]]}}, -{"type":"Feature","id":"01007","properties":{"name":"Bibb"},"geometry":{"type":"Polygon","coordinates":[[[-87.063542,33.248559],[-87.025203,33.248559],[-86.882803,33.051389],[-87.019726,32.837788],[-87.326435,32.876127],[-87.419543,32.876127],[-87.419543,33.002096],[-87.063542,33.248559]]]}}, -{"type":"Feature","id":"01009","properties":{"name":"Blount"},"geometry":{"type":"Polygon","coordinates":[[[-86.488463,34.261793],[-86.455601,34.261793],[-86.302247,34.097484],[-86.324155,33.938653],[-86.576094,33.763391],[-86.685633,33.796253],[-86.954003,33.812683],[-86.964957,33.856499],[-86.488463,34.261793]]]}}, -{"type":"Feature","id":"01011","properties":{"name":"Bullock"},"geometry":{"type":"Polygon","coordinates":[[[-85.918861,32.273663],[-85.431413,32.235325],[-85.409506,32.147694],[-85.655968,31.879324],[-85.995538,32.049109],[-85.918861,32.273663]]]}}, -{"type":"Feature","id":"01013","properties":{"name":"Butler"},"geometry":{"type":"Polygon","coordinates":[[[-86.477509,31.966955],[-86.450124,31.966955],[-86.499417,31.523322],[-86.702064,31.523322],[-86.90471,31.753354],[-86.90471,31.830031],[-86.855418,31.961478],[-86.477509,31.966955]]]}}, -{"type":"Feature","id":"01015","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-85.738122,33.966038],[-85.529998,33.94413],[-85.798368,33.555267],[-86.143416,33.681237],[-86.066738,33.840068],[-85.738122,33.966038]]]}}, -{"type":"Feature","id":"01017","properties":{"name":"Chambers"},"geometry":{"type":"Polygon","coordinates":[[[-85.404029,33.106158],[-85.234244,33.106158],[-85.184951,32.87065],[-85.130182,32.74468],[-85.184951,32.74468],[-85.595722,32.728249],[-85.595722,33.106158],[-85.404029,33.106158]]]}}, -{"type":"Feature","id":"01019","properties":{"name":"Cherokee"},"geometry":{"type":"Polygon","coordinates":[[[-85.513567,34.524686],[-85.464275,34.2837],[-85.42046,34.081054],[-85.398552,33.966038],[-85.529998,33.94413],[-85.738122,33.966038],[-85.842184,34.201546],[-85.513567,34.524686]]]}}, -{"type":"Feature","id":"01021","properties":{"name":"Chilton"},"geometry":{"type":"Polygon","coordinates":[[[-86.515848,33.018527],[-86.378924,32.755634],[-86.411786,32.706342],[-86.915664,32.662526],[-87.019726,32.728249],[-87.019726,32.837788],[-86.882803,33.051389],[-86.515848,33.018527]]]}}, -{"type":"Feature","id":"01023","properties":{"name":"Choctaw"},"geometry":{"type":"Polygon","coordinates":[[[-87.994621,32.312002],[-87.928898,32.312002],[-88.071299,31.988862],[-88.087729,31.698584],[-88.186314,31.698584],[-88.465638,31.698584],[-88.471115,31.895754],[-88.432777,32.229848],[-88.421823,32.306525],[-87.994621,32.312002]]]}}, -{"type":"Feature","id":"01025","properties":{"name":"Clarke"},"geometry":{"type":"Polygon","coordinates":[[[-87.819359,31.988862],[-87.666005,31.988862],[-87.501697,31.830031],[-87.76459,31.298768],[-87.945329,31.194706],[-88.087729,31.698584],[-88.071299,31.988862],[-87.819359,31.988862]]]}}, -{"type":"Feature","id":"01027","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-85.875046,33.500498],[-85.853138,33.500498],[-85.645014,33.495021],[-85.655968,33.106158],[-86.006492,33.089727],[-86.176277,33.106158],[-85.875046,33.500498]]]}}, -{"type":"Feature","id":"01029","properties":{"name":"Cleburne"},"geometry":{"type":"Polygon","coordinates":[[[-85.398552,33.966038],[-85.387598,33.900315],[-85.338305,33.653852],[-85.305444,33.484067],[-85.645014,33.495021],[-85.853138,33.500498],[-85.798368,33.555267],[-85.529998,33.94413],[-85.398552,33.966038]]]}}, -{"type":"Feature","id":"01031","properties":{"name":"Coffee"},"geometry":{"type":"Polygon","coordinates":[[[-86.055785,31.61643],[-85.787415,31.61643],[-85.792891,31.194706],[-86.192708,31.194706],[-86.192708,31.441168],[-86.143416,31.61643],[-86.055785,31.61643]]]}}, -{"type":"Feature","id":"01033","properties":{"name":"Colbert"},"geometry":{"type":"Polygon","coordinates":[[[-88.098683,34.891641],[-87.42502,34.798533],[-87.529082,34.568501],[-88.142499,34.579455],[-88.098683,34.891641]]]}}, -{"type":"Feature","id":"01035","properties":{"name":"Conecuh"},"geometry":{"type":"Polygon","coordinates":[[[-86.910187,31.753354],[-86.90471,31.753354],[-86.702064,31.523322],[-86.702064,31.194706],[-86.948526,31.260429],[-87.42502,31.260429],[-86.910187,31.753354]]]}}, -{"type":"Feature","id":"01037","properties":{"name":"Coosa"},"geometry":{"type":"Polygon","coordinates":[[[-86.176277,33.106158],[-86.006492,33.089727],[-86.006492,32.755634],[-86.378924,32.755634],[-86.515848,33.018527],[-86.488463,33.100681],[-86.176277,33.106158]]]}}, -{"type":"Feature","id":"01039","properties":{"name":"Covington"},"geometry":{"type":"Polygon","coordinates":[[[-86.400832,31.47403],[-86.192708,31.441168],[-86.192708,31.194706],[-86.187231,30.992059],[-86.389878,30.992059],[-86.685633,30.992059],[-86.702064,31.194706],[-86.702064,31.523322],[-86.499417,31.523322],[-86.400832,31.47403]]]}}, -{"type":"Feature","id":"01041","properties":{"name":"Crenshaw"},"geometry":{"type":"Polygon","coordinates":[[[-86.302247,31.988862],[-86.192708,31.966955],[-86.143416,31.61643],[-86.192708,31.441168],[-86.400832,31.47403],[-86.499417,31.523322],[-86.450124,31.966955],[-86.406309,32.049109],[-86.302247,31.988862]]]}}, -{"type":"Feature","id":"01043","properties":{"name":"Cullman"},"geometry":{"type":"Polygon","coordinates":[[[-86.986864,34.311085],[-86.581571,34.305608],[-86.455601,34.261793],[-86.488463,34.261793],[-86.964957,33.856499],[-87.151173,33.993423],[-87.107357,34.300131],[-87.112834,34.311085],[-86.986864,34.311085]]]}}, -{"type":"Feature","id":"01045","properties":{"name":"Dale"},"geometry":{"type":"Polygon","coordinates":[[[-85.694307,31.61643],[-85.414983,31.621907],[-85.414983,31.315199],[-85.710737,31.194706],[-85.792891,31.194706],[-85.787415,31.61643],[-85.749076,31.61643],[-85.694307,31.61643]]]}}, -{"type":"Feature","id":"01047","properties":{"name":"Dallas"},"geometry":{"type":"Polygon","coordinates":[[[-87.025203,32.717295],[-87.019726,32.728249],[-86.915664,32.662526],[-86.817079,32.339387],[-86.90471,32.049109],[-87.277142,32.147694],[-87.474312,32.262709],[-87.474312,32.306525],[-87.025203,32.717295]]]}}, -{"type":"Feature","id":"01049","properties":{"name":"DeKalb"},"geometry":{"type":"Polygon","coordinates":[[[-85.584768,34.858779],[-85.535475,34.623271],[-85.529998,34.590409],[-85.513567,34.524686],[-85.842184,34.201546],[-86.105077,34.201546],[-86.055785,34.475393],[-85.584768,34.858779]]]}}, -{"type":"Feature","id":"01051","properties":{"name":"Elmore"},"geometry":{"type":"Polygon","coordinates":[[[-86.006492,32.755634],[-85.885999,32.492741],[-86.022923,32.421541],[-86.307724,32.416064],[-86.411786,32.410587],[-86.411786,32.706342],[-86.378924,32.755634],[-86.006492,32.755634]]]}}, -{"type":"Feature","id":"01053","properties":{"name":"Escambia"},"geometry":{"type":"Polygon","coordinates":[[[-86.948526,31.260429],[-86.702064,31.194706],[-86.685633,30.992059],[-86.784218,30.997536],[-87.162127,30.997536],[-87.249758,30.997536],[-87.600282,30.997536],[-87.616713,31.243998],[-87.42502,31.260429],[-86.948526,31.260429]]]}}, -{"type":"Feature","id":"01055","properties":{"name":"Etowah"},"geometry":{"type":"Polygon","coordinates":[[[-86.105077,34.201546],[-85.842184,34.201546],[-85.738122,33.966038],[-86.066738,33.840068],[-86.291293,33.982469],[-86.324155,33.938653],[-86.302247,34.097484],[-86.105077,34.201546]]]}}, -{"type":"Feature","id":"01057","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-87.950806,33.922222],[-87.63862,33.916745],[-87.42502,33.60456],[-87.841267,33.522406],[-87.945329,33.522406],[-87.950806,33.922222]]]}}, -{"type":"Feature","id":"01059","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-88.142499,34.579455],[-87.529082,34.568501],[-87.529082,34.305608],[-87.633143,34.305608],[-88.175361,34.322039],[-88.15893,34.464439],[-88.142499,34.579455]]]}}, -{"type":"Feature","id":"01061","properties":{"name":"Geneva"},"geometry":{"type":"Polygon","coordinates":[[[-85.486183,31.200183],[-85.486183,30.997536],[-85.497137,30.997536],[-86.033877,30.992059],[-86.187231,30.992059],[-86.192708,31.194706],[-85.792891,31.194706],[-85.710737,31.194706],[-85.486183,31.200183]]]}}, -{"type":"Feature","id":"01063","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-87.83579,33.155451],[-87.715298,33.007573],[-87.813882,32.525602],[-87.852221,32.531079],[-88.169884,32.996619],[-87.83579,33.155451]]]}}, -{"type":"Feature","id":"01065","properties":{"name":"Hale"},"geometry":{"type":"Polygon","coordinates":[[[-87.644097,33.007573],[-87.419543,33.002096],[-87.419543,32.876127],[-87.523605,32.481787],[-87.813882,32.525602],[-87.715298,33.007573],[-87.644097,33.007573]]]}}, -{"type":"Feature","id":"01067","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-85.414983,31.621907],[-85.124705,31.764308],[-85.048028,31.517845],[-85.086366,31.309722],[-85.414983,31.315199],[-85.414983,31.621907]]]}}, -{"type":"Feature","id":"01069","properties":{"name":"Houston"},"geometry":{"type":"Polygon","coordinates":[[[-85.414983,31.315199],[-85.086366,31.309722],[-85.02612,31.074213],[-85.004212,31.003013],[-85.486183,30.997536],[-85.486183,31.200183],[-85.710737,31.194706],[-85.414983,31.315199]]]}}, -{"type":"Feature","id":"01071","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-85.864092,34.990226],[-85.606675,34.984749],[-85.584768,34.858779],[-86.055785,34.475393],[-86.329632,34.601363],[-86.313201,34.990226],[-85.864092,34.990226]]]}}, -{"type":"Feature","id":"01073","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-86.685633,33.796253],[-86.576094,33.763391],[-86.515848,33.544313],[-87.025203,33.248559],[-87.063542,33.248559],[-87.266188,33.511452],[-86.954003,33.812683],[-86.685633,33.796253]]]}}, -{"type":"Feature","id":"01075","properties":{"name":"Lamar"},"geometry":{"type":"Polygon","coordinates":[[[-88.208222,34.059146],[-87.950806,33.922222],[-87.945329,33.522406],[-88.273945,33.53336],[-88.246561,33.74696],[-88.208222,34.059146]]]}}, -{"type":"Feature","id":"01077","properties":{"name":"Lauderdale"},"geometry":{"type":"Polygon","coordinates":[[[-87.983668,35.006656],[-87.605759,35.00118],[-87.222373,35.00118],[-87.211419,35.00118],[-87.260711,34.760194],[-87.42502,34.798533],[-88.098683,34.891641],[-88.202745,34.995703],[-87.983668,35.006656]]]}}, -{"type":"Feature","id":"01079","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-87.42502,34.798533],[-87.260711,34.760194],[-87.107357,34.683517],[-87.112834,34.311085],[-87.107357,34.300131],[-87.529082,34.305608],[-87.529082,34.568501],[-87.42502,34.798533]]]}}, -{"type":"Feature","id":"01081","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-85.184951,32.74468],[-85.130182,32.74468],[-85.080889,32.607757],[-84.998735,32.509172],[-85.020643,32.509172],[-85.431413,32.410587],[-85.694307,32.580372],[-85.694307,32.596803],[-85.595722,32.728249],[-85.184951,32.74468]]]}}, -{"type":"Feature","id":"01083","properties":{"name":"Limestone"},"geometry":{"type":"Polygon","coordinates":[[[-87.211419,35.00118],[-86.838987,34.990226],[-86.784218,34.990226],[-86.789695,34.55207],[-87.03068,34.650655],[-87.107357,34.683517],[-87.260711,34.760194],[-87.211419,35.00118]]]}}, -{"type":"Feature","id":"01085","properties":{"name":"Lowndes"},"geometry":{"type":"Polygon","coordinates":[[[-86.499417,32.344863],[-86.406309,32.049109],[-86.450124,31.966955],[-86.477509,31.966955],[-86.855418,31.961478],[-86.90471,32.049109],[-86.817079,32.339387],[-86.499417,32.344863]]]}}, -{"type":"Feature","id":"01087","properties":{"name":"Macon"},"geometry":{"type":"Polygon","coordinates":[[[-85.694307,32.580372],[-85.431413,32.410587],[-85.431413,32.235325],[-85.918861,32.273663],[-86.022923,32.421541],[-85.885999,32.492741],[-85.694307,32.596803],[-85.694307,32.580372]]]}}, -{"type":"Feature","id":"01089","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-86.784218,34.990226],[-86.318678,34.990226],[-86.313201,34.990226],[-86.329632,34.601363],[-86.548709,34.546593],[-86.789695,34.55207],[-86.784218,34.990226]]]}}, -{"type":"Feature","id":"01091","properties":{"name":"Marengo"},"geometry":{"type":"Polygon","coordinates":[[[-87.813882,32.525602],[-87.523605,32.481787],[-87.474312,32.306525],[-87.474312,32.262709],[-87.666005,31.988862],[-87.819359,31.988862],[-88.071299,31.988862],[-87.928898,32.312002],[-87.852221,32.531079],[-87.813882,32.525602]]]}}, -{"type":"Feature","id":"01093","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-88.175361,34.322039],[-87.633143,34.305608],[-87.63862,34.004376],[-87.63862,33.916745],[-87.950806,33.922222],[-88.208222,34.059146],[-88.202745,34.08653],[-88.175361,34.322039]]]}}, -{"type":"Feature","id":"01095","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-86.329632,34.601363],[-86.055785,34.475393],[-86.105077,34.201546],[-86.302247,34.097484],[-86.455601,34.261793],[-86.581571,34.305608],[-86.548709,34.546593],[-86.329632,34.601363]]]}}, -{"type":"Feature","id":"01097","properties":{"name":"Mobile"},"geometry":{"type":"Polygon","coordinates":[[[-87.972714,31.161844],[-88.005575,30.685351],[-88.394438,30.367688],[-88.410869,30.734643],[-88.4273,30.997536],[-88.432777,31.112552],[-87.972714,31.161844]]]}}, -{"type":"Feature","id":"01099","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-87.501697,31.830031],[-86.90471,31.830031],[-86.90471,31.753354],[-86.910187,31.753354],[-87.42502,31.260429],[-87.616713,31.243998],[-87.76459,31.298768],[-87.501697,31.830031]]]}}, -{"type":"Feature","id":"01101","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-86.307724,32.416064],[-86.022923,32.421541],[-85.918861,32.273663],[-85.995538,32.049109],[-86.192708,31.966955],[-86.302247,31.988862],[-86.406309,32.049109],[-86.499417,32.344863],[-86.411786,32.410587],[-86.307724,32.416064]]]}}, -{"type":"Feature","id":"01103","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-87.03068,34.650655],[-86.789695,34.55207],[-86.548709,34.546593],[-86.581571,34.305608],[-86.986864,34.311085],[-87.112834,34.311085],[-87.107357,34.683517],[-87.03068,34.650655]]]}}, -{"type":"Feature","id":"01105","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-87.326435,32.876127],[-87.019726,32.837788],[-87.019726,32.728249],[-87.025203,32.717295],[-87.474312,32.306525],[-87.523605,32.481787],[-87.419543,32.876127],[-87.326435,32.876127]]]}}, -{"type":"Feature","id":"01107","properties":{"name":"Pickens"},"geometry":{"type":"Polygon","coordinates":[[[-88.273945,33.53336],[-87.945329,33.522406],[-87.841267,33.522406],[-87.83579,33.155451],[-88.169884,32.996619],[-88.339669,32.991142],[-88.306807,33.286897],[-88.273945,33.53336]]]}}, -{"type":"Feature","id":"01109","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-85.995538,32.049109],[-85.655968,31.879324],[-85.749076,31.61643],[-85.787415,31.61643],[-86.055785,31.61643],[-86.143416,31.61643],[-86.192708,31.966955],[-85.995538,32.049109]]]}}, -{"type":"Feature","id":"01111","properties":{"name":"Randolph"},"geometry":{"type":"Polygon","coordinates":[[[-85.645014,33.495021],[-85.305444,33.484067],[-85.29449,33.429298],[-85.234244,33.128066],[-85.234244,33.106158],[-85.404029,33.106158],[-85.595722,33.106158],[-85.655968,33.106158],[-85.645014,33.495021]]]}}, -{"type":"Feature","id":"01113","properties":{"name":"Russell"},"geometry":{"type":"Polygon","coordinates":[[[-85.020643,32.509172],[-84.998735,32.509172],[-84.982304,32.372248],[-84.922058,32.229848],[-85.053504,32.06554],[-85.354736,32.147694],[-85.409506,32.147694],[-85.431413,32.235325],[-85.431413,32.410587],[-85.020643,32.509172]]]}}, -{"type":"Feature","id":"01115","properties":{"name":"St. Clair"},"geometry":{"type":"Polygon","coordinates":[[[-86.291293,33.982469],[-86.066738,33.840068],[-86.143416,33.681237],[-86.198185,33.697668],[-86.378924,33.390959],[-86.515848,33.544313],[-86.576094,33.763391],[-86.324155,33.938653],[-86.291293,33.982469]]]}}, -{"type":"Feature","id":"01117","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-86.515848,33.544313],[-86.378924,33.390959],[-86.488463,33.100681],[-86.515848,33.018527],[-86.882803,33.051389],[-87.025203,33.248559],[-86.515848,33.544313]]]}}, -{"type":"Feature","id":"01119","properties":{"name":"Sumter"},"geometry":{"type":"Polygon","coordinates":[[[-88.339669,32.991142],[-88.169884,32.996619],[-87.852221,32.531079],[-87.928898,32.312002],[-87.994621,32.312002],[-88.421823,32.306525],[-88.388961,32.580372],[-88.345146,32.930896],[-88.339669,32.991142]]]}}, -{"type":"Feature","id":"01121","properties":{"name":"Talladega"},"geometry":{"type":"Polygon","coordinates":[[[-86.198185,33.697668],[-86.143416,33.681237],[-85.798368,33.555267],[-85.853138,33.500498],[-85.875046,33.500498],[-86.176277,33.106158],[-86.488463,33.100681],[-86.378924,33.390959],[-86.198185,33.697668]]]}}, -{"type":"Feature","id":"01123","properties":{"name":"Tallapoosa"},"geometry":{"type":"Polygon","coordinates":[[[-85.655968,33.106158],[-85.595722,33.106158],[-85.595722,32.728249],[-85.694307,32.596803],[-85.885999,32.492741],[-86.006492,32.755634],[-86.006492,33.089727],[-85.655968,33.106158]]]}}, -{"type":"Feature","id":"01125","properties":{"name":"Tuscaloosa"},"geometry":{"type":"Polygon","coordinates":[[[-87.841267,33.522406],[-87.42502,33.60456],[-87.266188,33.511452],[-87.063542,33.248559],[-87.419543,33.002096],[-87.644097,33.007573],[-87.715298,33.007573],[-87.83579,33.155451],[-87.841267,33.522406]]]}}, -{"type":"Feature","id":"01127","properties":{"name":"Walker"},"geometry":{"type":"Polygon","coordinates":[[[-87.627666,34.004376],[-87.151173,33.993423],[-86.964957,33.856499],[-86.954003,33.812683],[-87.266188,33.511452],[-87.42502,33.60456],[-87.63862,33.916745],[-87.63862,34.004376],[-87.627666,34.004376]]]}}, -{"type":"Feature","id":"01129","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-88.186314,31.698584],[-88.087729,31.698584],[-87.945329,31.194706],[-87.972714,31.161844],[-88.432777,31.112552],[-88.449208,31.435691],[-88.465638,31.698584],[-88.186314,31.698584]]]}}, -{"type":"Feature","id":"01131","properties":{"name":"Wilcox"},"geometry":{"type":"Polygon","coordinates":[[[-87.277142,32.147694],[-86.90471,32.049109],[-86.855418,31.961478],[-86.90471,31.830031],[-87.501697,31.830031],[-87.666005,31.988862],[-87.474312,32.262709],[-87.277142,32.147694]]]}}, -{"type":"Feature","id":"01133","properties":{"name":"Winston"},"geometry":{"type":"Polygon","coordinates":[[[-87.633143,34.305608],[-87.529082,34.305608],[-87.107357,34.300131],[-87.151173,33.993423],[-87.627666,34.004376],[-87.63862,34.004376],[-87.633143,34.305608]]]}}, -{"type":"Feature","id":"02013","properties":{"name":"Aleutians East"},"geometry":{"type":"Polygon","coordinates":[[[-158.893615,56.793925],[-159.901372,56.492694],[-159.86851,55.89023],[-159.561801,55.632814],[-159.813741,55.857368],[-160.536697,55.473983],[-161.506115,55.364444],[-161.960701,55.107028],[-163.034181,54.942719],[-163.587352,54.614103],[-164.847049,54.416933],[-164.551294,54.88795],[-162.880827,55.183705],[-161.807347,55.89023],[-160.585989,55.988815],[-159.813741,56.547463],[-158.893615,56.804879],[-158.893615,56.793925]]]}}, -{"type":"Feature","id":"02016","properties":{"name":"Aleutians West"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-166.375115,54.01164],[-166.117699,53.852808],[-166.878994,53.431084],[-167.032348,53.945916],[-166.375115,54.01164]]],[[[-168.790446,53.157237],[-168.007243,53.568007],[-167.842935,53.387268],[-168.971185,52.877913],[-168.790446,53.157237]]]]}}, -{"type":"Feature","id":"02020","properties":{"name":"Anchorage"},"geometry":{"type":"Polygon","coordinates":[[[-149.259676,61.482186],[-148.460043,61.427417],[-148.470997,60.852338],[-148.744844,60.731845],[-149.730693,60.994739],[-149.73617,60.994739],[-149.988109,61.230247],[-149.259676,61.482186]]]}}, -{"type":"Feature","id":"02050","properties":{"name":"Bethel"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-153.000427,62.292773],[-153.000427,61.427417],[-153.427628,61.427417],[-153.438582,60.907107],[-155.963451,60.907107],[-158.942907,60.901631],[-159.364631,60.644214],[-160.021864,59.784335],[-160.821498,59.264025],[-161.035098,58.842301],[-161.095345,58.820393],[-161.347284,58.732762],[-161.752577,58.552023],[-162.048332,59.253071],[-161.703285,59.48858],[-162.234548,60.091043],[-163.171105,59.844581],[-164.113139,59.839104],[-164.189816,60.02532],[-165.361881,60.507291],[-165.159234,60.918061],[-164.156954,61.022123],[-163.992646,61.372647],[-162.508395,61.558863],[-161.900455,61.482186],[-160.40525,61.810803],[-160.536697,61.947726],[-159.266046,61.947726],[-158.532136,62.117511],[-157.064316,62.02988],[-153.734337,62.02988],[-153.000427,62.292773]]],[[[-166.364161,60.359413],[-165.685021,60.277259],[-165.575482,59.904827],[-166.062929,59.745996],[-167.344534,60.074613],[-166.364161,60.359413]]]]}}, -{"type":"Feature","id":"02060","properties":{"name":"Bristol Bay"},"geometry":{"type":"Polygon","coordinates":[[[-156.987639,58.886116],[-156.319453,58.89707],[-156.319453,58.612269],[-157.266963,58.612269],[-156.987639,58.886116]]]}}, -{"type":"Feature","id":"02068","properties":{"name":"Denali"},"geometry":{"type":"Polygon","coordinates":[[[-149.232292,64.35758],[-147.99998,64.341149],[-147.003177,64.258995],[-146.975792,63.481269],[-148.038319,63.333392],[-149.506139,63.333392],[-151.888608,62.796652],[-153.000427,62.725452],[-152.436302,63.169084],[-152.852549,63.651055],[-152.244609,63.656532],[-152.047439,64.001579],[-151.302575,64.012533],[-150.749404,64.363057],[-149.232292,64.35758]]]}}, -{"type":"Feature","id":"02070","properties":{"name":"Dillingham"},"geometry":{"type":"Polygon","coordinates":[[[-155.963451,60.907107],[-155.957974,59.674796],[-157.245055,59.247595],[-157.157424,58.858732],[-158.039212,58.634177],[-158.619768,58.913501],[-158.701922,58.480823],[-159.0634,58.420577],[-159.731586,58.929932],[-160.317619,59.072332],[-161.035098,58.842301],[-160.821498,59.264025],[-160.021864,59.784335],[-159.364631,60.644214],[-158.942907,60.901631],[-155.963451,60.907107]]]}}, -{"type":"Feature","id":"02090","properties":{"name":"Fairbanks North Star"},"geometry":{"type":"Polygon","coordinates":[[[-146.696468,65.321521],[-146.19259,65.452968],[-145.644896,65.031244],[-143.886798,65.09149],[-144.06206,64.680719],[-146.236405,64.308287],[-147.003177,64.258995],[-147.99998,64.341149],[-148.646259,64.604042],[-148.66269,65.211983],[-146.696468,65.321521]]]}}, -{"type":"Feature","id":"02100","properties":{"name":"Haines"},"geometry":{"type":"Polygon","coordinates":[[[-135.72068,59.729565],[-135.030585,59.346179],[-134.329537,58.962794],[-135.178463,58.973748],[-135.38111,59.033994],[-135.05797,58.190545],[-135.446833,58.398669],[-135.567326,58.946363],[-136.487451,59.258548],[-136.25742,59.625503],[-135.72068,59.729565]]]}}, -{"type":"Feature","id":"02110","properties":{"name":"Juneau"},"geometry":{"type":"Polygon","coordinates":[[[-135.178463,58.973748],[-134.329537,58.962794],[-133.382026,58.426053],[-133.173903,58.152206],[-133.529904,57.911221],[-133.601104,57.861929],[-135.074401,58.502731],[-135.178463,58.973748]]]}}, -{"type":"Feature","id":"02122","properties":{"name":"Kenai Peninsula"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-153.427628,61.427417],[-153.000427,61.427417],[-151.335437,61.42194],[-150.973959,61.191908],[-152.080301,60.693507],[-152.567748,60.069136],[-153.214027,59.636457],[-153.608367,59.620026],[-154.260123,59.143533],[-153.312612,58.847778],[-153.329043,58.853255],[-154.303938,58.645131],[-154.638032,58.645131],[-154.747571,59.253071],[-153.652183,59.784335],[-153.438582,60.907107],[-153.427628,61.427417]]],[[[-149.730693,60.994739],[-148.744844,60.731845],[-148.586013,59.959597],[-149.358261,60.101997],[-149.741647,59.729565],[-151.592853,59.159963],[-151.888608,59.422857],[-151.160175,59.592642],[-151.8667,59.778858],[-151.423068,60.211536],[-151.406637,60.720892],[-150.404357,61.038554],[-149.73617,60.994739],[-149.730693,60.994739]]]]}}, -{"type":"Feature","id":"02130","properties":{"name":"Ketchikan Gateway"},"geometry":{"type":"Polygon","coordinates":[[[-131.706083,55.89023],[-131.240543,55.977861],[-131.032419,55.28229],[-131.843006,55.457552],[-131.706083,55.89023]]]}}, -{"type":"Feature","id":"02150","properties":{"name":"Kodiak Island"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-153.329043,58.853255],[-153.312612,58.847778],[-154.062953,58.4863],[-154.210831,58.135776],[-155.120003,57.955037],[-156.357791,57.16088],[-156.752131,57.16088],[-155.328126,57.878359],[-155.333603,58.190545],[-154.468247,58.36033],[-154.303938,58.645131],[-153.329043,58.853255]]],[[[-152.94018,58.026237],[-152.666333,58.562977],[-152.080301,58.152206],[-152.94018,58.026237]]],[[[-153.958891,57.538789],[-153.936983,57.812636],[-153.301658,57.993375],[-152.151501,57.620943],[-153.695998,56.859649],[-154.303938,56.848695],[-154.742094,57.314235],[-154.227261,57.659282],[-153.958891,57.538789]]]]}}, -{"type":"Feature","id":"02164","properties":{"name":"Lake and Peninsula"},"geometry":{"type":"Polygon","coordinates":[[[-153.438582,60.907107],[-153.652183,59.784335],[-154.747571,59.253071],[-154.638032,58.645131],[-154.303938,58.645131],[-154.468247,58.36033],[-155.333603,58.190545],[-155.328126,57.878359],[-156.752131,57.16088],[-156.357791,57.16088],[-157.464133,56.62414],[-158.32949,56.48174],[-158.115889,56.2298],[-158.510229,55.977861],[-159.496078,55.857368],[-159.561801,55.632814],[-159.86851,55.89023],[-159.901372,56.492694],[-158.893615,56.793925],[-158.893615,56.804879],[-158.378782,57.264942],[-157.601057,57.609989],[-157.453179,58.508208],[-157.266963,58.612269],[-156.319453,58.612269],[-156.319453,58.89707],[-156.987639,58.886116],[-157.157424,58.858732],[-157.245055,59.247595],[-155.957974,59.674796],[-155.963451,60.907107],[-153.438582,60.907107]]]}}, -{"type":"Feature","id":"02170","properties":{"name":"Matanuska-Susitna"},"geometry":{"type":"Polygon","coordinates":[[[-153.000427,62.725452],[-151.888608,62.796652],[-149.506139,63.333392],[-148.038319,63.333392],[-146.975792,63.481269],[-146.488345,63.481269],[-146.482868,63.174561],[-146.428098,62.248958],[-146.981269,62.248958],[-146.942931,61.476709],[-148.460043,61.427417],[-149.259676,61.482186],[-149.988109,61.230247],[-150.973959,61.191908],[-151.335437,61.42194],[-153.000427,61.427417],[-153.000427,62.292773],[-153.000427,62.725452]]]}}, -{"type":"Feature","id":"02180","properties":{"name":"Nome"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-164.403417,66.581218],[-164.244585,65.781584],[-163.757138,65.436537],[-159.802787,65.436537],[-159.594663,65.524168],[-159.578232,64.921705],[-159.978049,64.746443],[-159.956141,64.050871],[-159.698725,63.793455],[-160.690051,63.536039],[-160.848882,63.010253],[-161.993563,63.010253],[-162.585072,63.273146],[-162.294794,63.541516],[-161.13916,63.503177],[-160.766728,63.771547],[-161.374669,64.532842],[-160.783159,64.719058],[-161.144637,64.921705],[-162.541257,64.532842],[-162.787719,64.324718],[-163.598306,64.565704],[-165.000403,64.434257],[-166.188899,64.576658],[-166.884471,65.140782],[-166.34773,65.277706],[-167.47598,65.414629],[-168.105828,65.682999],[-165.88219,66.312848],[-164.403417,66.581218]]],[[[-171.742517,63.716778],[-170.94836,63.5689],[-170.488297,63.69487],[-169.518879,63.366254],[-168.686384,63.295053],[-169.639372,62.939052],[-170.866206,63.415546],[-171.463193,63.306007],[-171.742517,63.716778]]]]}}, -{"type":"Feature","id":"02185","properties":{"name":"North Slope"},"geometry":{"type":"Polygon","coordinates":[[[-141.00045,68.498147],[-146.000897,68.487193],[-145.99542,67.999745],[-146.970315,67.999745],[-155.300742,67.999745],[-157.157424,68.207869],[-161.993563,68.2243],[-162.683657,68.300977],[-164.502001,68.229777],[-164.496525,68.021653],[-165.361881,68.02713],[-166.681824,68.339316],[-166.216284,68.881533],[-164.255539,68.930825],[-163.110859,69.374457],[-163.034181,69.724981],[-161.851162,70.311014],[-161.396576,70.239814],[-159.649432,70.792985],[-158.033735,70.831323],[-156.812377,71.285909],[-155.585543,71.170894],[-155.974405,70.809416],[-155.032372,71.148986],[-154.183446,70.7656],[-153.235935,70.924431],[-152.26104,70.842277],[-152.419871,70.606769],[-151.877654,70.431507],[-149.462323,70.519138],[-147.682318,70.201475],[-145.858496,70.168614],[-144.620708,69.971444],[-143.914183,70.130275],[-142.747594,70.042644],[-141.378359,69.63735],[-141.00045,69.648304],[-141.00045,68.498147]]]}}, -{"type":"Feature","id":"02188","properties":{"name":"Northwest Arctic"},"geometry":{"type":"Polygon","coordinates":[[[-162.683657,68.300977],[-161.993563,68.2243],[-157.157424,68.207869],[-155.300742,67.999745],[-155.350034,67.775191],[-154.687324,67.599929],[-154.747571,67.254881],[-154.145107,67.161773],[-154.199877,66.718141],[-155.514342,66.570264],[-155.563635,66.307371],[-157.891334,66.477156],[-157.896811,66.126632],[-158.964815,66.121155],[-159.594663,65.956846],[-159.594663,65.524168],[-159.802787,65.436537],[-163.757138,65.436537],[-164.244585,65.781584],[-164.403417,66.581218],[-163.751661,66.553833],[-163.768091,66.060908],[-161.840208,66.02257],[-160.991283,66.23617],[-162.502918,66.740049],[-161.884024,66.718141],[-161.851162,67.052235],[-162.902735,67.008419],[-163.740707,67.128912],[-164.009077,67.534205],[-165.361881,68.02713],[-164.496525,68.021653],[-164.502001,68.229777],[-162.683657,68.300977]]]}}, -{"type":"Feature","id":"02201","properties":{"name":"Prince of Wales-Outer Ketchikan"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-130.99408,56.262662],[-131.065281,56.405062],[-130.101339,56.114785],[-129.980846,55.28229],[-130.336847,54.920812],[-130.917403,54.789365],[-131.092665,55.189182],[-130.900972,55.698537],[-131.240543,55.977861],[-131.706083,55.89023],[-131.974453,55.49589],[-132.220915,55.736876],[-130.99408,56.262662]]],[[[-133.595627,56.350293],[-133.162949,56.317431],[-131.97993,55.178228],[-132.029222,54.701734],[-132.544054,55.096074],[-132.867194,54.701734],[-133.157472,54.95915],[-133.102702,55.42469],[-133.694212,55.780691],[-133.32178,55.81903],[-133.595627,56.350293]]]]}}, -{"type":"Feature","id":"02220","properties":{"name":"Sitka"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-136.372436,57.829067],[-135.589233,57.89479],[-134.937477,57.763344],[-134.822462,57.500451],[-135.572802,57.675713],[-135.890465,57.407343],[-136.372436,57.829067]]],[[[-134.66363,56.28457],[-134.669107,56.169554],[-135.413971,56.810356],[-135.687818,57.369004],[-135.419448,57.566174],[-134.849846,57.407343],[-134.636246,56.28457],[-134.66363,56.28457]]]]}}, -{"type":"Feature","id":"02232","properties":{"name":"Skagway-Hoonah-Angoon"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-135.030585,59.346179],[-135.72068,59.729565],[-135.025108,59.565257],[-135.030585,59.346179]]],[[[-135.567326,58.946363],[-135.446833,58.398669],[-136.591513,58.21793],[-137.944318,58.803962],[-137.522593,58.908024],[-136.487451,59.258548],[-135.567326,58.946363]]],[[[-134.712923,58.223407],[-134.176183,58.157683],[-133.869474,57.363527],[-134.565045,57.023957],[-134.712923,58.223407]]],[[[-135.589233,57.89479],[-136.372436,57.829067],[-136.377913,58.267222],[-135.780926,58.28913],[-134.91557,57.976944],[-135.589233,57.89479]]],[[[-133.529904,57.911221],[-133.173903,58.152206],[-132.368792,57.347096],[-133.12461,57.188265],[-133.51895,57.177311],[-133.601104,57.861929],[-133.529904,57.911221]]]]}}, -{"type":"Feature","id":"02240","properties":{"name":"Southeast Fairbanks"},"geometry":{"type":"Polygon","coordinates":[[[-141.838422,65.463922],[-141.00045,65.841831],[-141.00045,61.903911],[-141.827468,61.898434],[-141.964392,62.511851],[-142.314916,62.681636],[-143.103595,62.615913],[-143.125503,63.114314],[-145.146494,63.136222],[-145.360095,63.223853],[-146.482868,63.174561],[-146.488345,63.481269],[-146.975792,63.481269],[-147.003177,64.258995],[-146.236405,64.308287],[-144.06206,64.680719],[-142.605194,65.392722],[-141.838422,65.463922]]]}}, -{"type":"Feature","id":"02261","properties":{"name":"Valdez-Cordova"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-145.360095,63.223853],[-145.146494,63.136222],[-143.125503,63.114314],[-143.103595,62.615913],[-142.314916,62.681636],[-141.964392,62.511851],[-141.827468,61.898434],[-141.00045,61.903911],[-141.00045,60.392275],[-141.78913,60.518245],[-143.169319,60.518245],[-143.886798,59.997935],[-144.231845,60.140336],[-146.110436,60.468952],[-146.044712,60.742799],[-146.669084,60.693507],[-146.745761,60.9564],[-148.366935,60.764707],[-147.961642,60.140336],[-148.586013,59.959597],[-148.744844,60.731845],[-148.470997,60.852338],[-148.460043,61.427417],[-146.942931,61.476709],[-146.981269,62.248958],[-146.428098,62.248958],[-146.482868,63.174561],[-145.360095,63.223853]]],[[[-147.079854,60.200582],[-147.874011,59.784335],[-147.112716,60.381321],[-147.079854,60.200582]]]]}}, -{"type":"Feature","id":"02270","properties":{"name":"Wade Hampton"},"geometry":{"type":"Polygon","coordinates":[[[-162.585072,63.273146],[-161.993563,63.010253],[-160.848882,63.010253],[-161.046052,62.205142],[-160.536697,61.947726],[-160.40525,61.810803],[-161.900455,61.482186],[-162.508395,61.558863],[-163.992646,61.372647],[-164.156954,61.022123],[-165.159234,60.918061],[-164.962064,61.022123],[-166.106745,61.49314],[-165.59739,61.860095],[-165.674067,62.139419],[-165.044219,62.539236],[-164.633448,63.097884],[-164.069323,63.262192],[-163.313505,63.037637],[-162.585072,63.273146]]]}}, -{"type":"Feature","id":"02280","properties":{"name":"Wrangell-Petersburg"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-133.12461,57.188265],[-132.368792,57.347096],[-131.837529,56.602232],[-131.065281,56.405062],[-130.99408,56.262662],[-132.220915,55.736876],[-132.719317,56.218847],[-132.450946,56.673433],[-133.51895,57.177311],[-133.12461,57.188265]]],[[[-133.907813,56.930849],[-133.102702,57.007526],[-132.538577,56.585802],[-133.66135,56.448878],[-133.907813,56.930849]]],[[[-134.115936,56.48174],[-134.417168,56.848695],[-133.880428,56.722725],[-134.115936,56.48174]]],[[[-134.66363,56.28457],[-134.636246,56.28457],[-134.669107,56.169554],[-134.66363,56.28457]]]]}}, -{"type":"Feature","id":"02282","properties":{"name":"Yakutat"},"geometry":{"type":"Polygon","coordinates":[[[-137.522593,58.908024],[-137.944318,58.803962],[-138.11958,59.02304],[-139.85577,59.537872],[-139.625738,59.88292],[-140.315833,59.696704],[-141.46599,59.970551],[-142.906426,60.091043],[-143.886798,59.997935],[-143.169319,60.518245],[-141.78913,60.518245],[-141.00045,60.392275],[-139.987216,60.184151],[-139.088998,60.359413],[-139.198537,60.091043],[-137.604747,59.242118],[-137.522593,58.908024]]]}}, -{"type":"Feature","id":"02290","properties":{"name":"Yukon-Koyukuk"},"geometry":{"type":"Polygon","coordinates":[[[-146.970315,67.999745],[-145.99542,67.999745],[-146.000897,68.487193],[-141.00045,68.498147],[-141.00045,65.841831],[-141.838422,65.463922],[-142.605194,65.392722],[-144.06206,64.680719],[-143.886798,65.09149],[-145.644896,65.031244],[-146.19259,65.452968],[-146.696468,65.321521],[-148.66269,65.211983],[-148.646259,64.604042],[-147.99998,64.341149],[-149.232292,64.35758],[-150.749404,64.363057],[-151.302575,64.012533],[-152.047439,64.001579],[-152.244609,63.656532],[-152.852549,63.651055],[-152.436302,63.169084],[-153.000427,62.725452],[-153.000427,62.292773],[-153.734337,62.02988],[-157.064316,62.02988],[-158.532136,62.117511],[-159.266046,61.947726],[-160.536697,61.947726],[-161.046052,62.205142],[-160.848882,63.010253],[-160.690051,63.536039],[-159.698725,63.793455],[-159.956141,64.050871],[-159.978049,64.746443],[-159.578232,64.921705],[-159.594663,65.524168],[-159.594663,65.956846],[-158.964815,66.121155],[-157.896811,66.126632],[-157.891334,66.477156],[-155.563635,66.307371],[-155.514342,66.570264],[-154.199877,66.718141],[-154.145107,67.161773],[-154.747571,67.254881],[-154.687324,67.599929],[-155.350034,67.775191],[-155.300742,67.999745],[-146.970315,67.999745]]]}}, -{"type":"Feature","id":"04001","properties":{"name":"Apache"},"geometry":{"type":"Polygon","coordinates":[[[-110.000968,37.000263],[-109.042503,37.000263],[-109.04798,36.00346],[-109.04798,34.957364],[-109.04798,34.579455],[-109.04798,33.779822],[-109.497089,33.653852],[-109.743552,33.500498],[-109.891429,33.566221],[-109.842137,35.516012],[-110.000968,35.663889],[-110.000968,37.000263]]]}}, -{"type":"Feature","id":"04003","properties":{"name":"Cochise"},"geometry":{"type":"Polygon","coordinates":[[[-109.831183,32.427018],[-109.113704,32.427018],[-109.04798,32.427018],[-109.04798,31.331629],[-110.461031,31.331629],[-110.450077,31.731446],[-110.450077,32.427018],[-109.831183,32.427018]]]}}, -{"type":"Feature","id":"04005","properties":{"name":"Coconino"},"geometry":{"type":"Polygon","coordinates":[[[-110.751309,37.00574],[-110.751309,34.261793],[-111.556419,34.469916],[-111.775497,34.979272],[-112.334144,34.973795],[-112.438206,35.258596],[-113.336425,35.526966],[-113.352855,36.047275],[-112.629899,36.392322],[-112.542268,37.000263],[-111.414018,37.000263],[-110.751309,37.00574]]]}}, -{"type":"Feature","id":"04007","properties":{"name":"Gila"},"geometry":{"type":"Polygon","coordinates":[[[-111.556419,34.469916],[-110.751309,34.261793],[-110.751309,33.998899],[-110.000968,33.998899],[-110.000968,33.577175],[-110.450077,33.193789],[-110.778693,32.985665],[-111.041587,33.467636],[-111.496173,33.998899],[-111.556419,34.469916]]]}}, -{"type":"Feature","id":"04009","properties":{"name":"Graham"},"geometry":{"type":"Polygon","coordinates":[[[-109.743552,33.500498],[-109.497089,33.653852],[-109.497089,33.078773],[-109.113704,32.427018],[-109.831183,32.427018],[-110.450077,32.427018],[-110.450077,32.514649],[-110.450077,33.193789],[-110.000968,33.577175],[-109.891429,33.566221],[-109.743552,33.500498]]]}}, -{"type":"Feature","id":"04011","properties":{"name":"Greenlee"},"geometry":{"type":"Polygon","coordinates":[[[-109.497089,33.653852],[-109.04798,33.779822],[-109.04798,33.21022],[-109.04798,32.777542],[-109.04798,32.427018],[-109.113704,32.427018],[-109.497089,33.078773],[-109.497089,33.653852]]]}}, -{"type":"Feature","id":"04012","properties":{"name":"La Paz"},"geometry":{"type":"Polygon","coordinates":[[[-113.418579,34.300131],[-113.330948,34.316562],[-113.336425,33.998899],[-113.336425,33.380005],[-113.993657,33.462159],[-114.513967,33.029481],[-114.628982,33.434775],[-114.43729,34.081054],[-114.136058,34.305608],[-113.418579,34.300131]]]}}, -{"type":"Feature","id":"04013","properties":{"name":"Maricopa"},"geometry":{"type":"Polygon","coordinates":[[[-111.496173,33.998899],[-111.041587,33.467636],[-111.578327,33.467636],[-111.583804,33.204743],[-112.202698,33.308805],[-112.202698,32.509172],[-113.336425,32.503695],[-113.336425,33.380005],[-113.336425,33.998899],[-112.273898,33.883884],[-111.496173,33.998899]]]}}, -{"type":"Feature","id":"04015","properties":{"name":"Mohave"},"geometry":{"type":"Polygon","coordinates":[[[-112.898269,37.000263],[-112.542268,37.000263],[-112.629899,36.392322],[-113.352855,36.047275],[-113.336425,35.526966],[-113.330948,34.316562],[-113.418579,34.300131],[-114.136058,34.305608],[-114.634459,35.00118],[-114.754952,36.085614],[-114.048427,36.195153],[-114.048427,36.841432],[-114.048427,37.000263],[-112.898269,37.000263]]]}}, -{"type":"Feature","id":"04017","properties":{"name":"Navajo"},"geometry":{"type":"Polygon","coordinates":[[[-110.000968,37.000263],[-110.000968,35.663889],[-109.842137,35.516012],[-109.891429,33.566221],[-110.000968,33.577175],[-110.000968,33.998899],[-110.751309,33.998899],[-110.751309,34.261793],[-110.751309,37.00574],[-110.000968,37.000263]]]}}, -{"type":"Feature","id":"04019","properties":{"name":"Pima"},"geometry":{"type":"Polygon","coordinates":[[[-110.696539,32.514649],[-110.450077,32.514649],[-110.450077,32.427018],[-110.450077,31.731446],[-110.789647,31.731446],[-111.364726,31.424737],[-113.336425,32.038155],[-113.336425,32.503695],[-112.202698,32.509172],[-110.696539,32.514649]]]}}, -{"type":"Feature","id":"04021","properties":{"name":"Pinal"},"geometry":{"type":"Polygon","coordinates":[[[-111.578327,33.467636],[-111.041587,33.467636],[-110.778693,32.985665],[-110.450077,33.193789],[-110.450077,32.514649],[-110.696539,32.514649],[-112.202698,32.509172],[-112.202698,33.308805],[-111.583804,33.204743],[-111.578327,33.467636]]]}}, -{"type":"Feature","id":"04023","properties":{"name":"Santa Cruz"},"geometry":{"type":"Polygon","coordinates":[[[-110.789647,31.731446],[-110.450077,31.731446],[-110.461031,31.331629],[-111.364726,31.424737],[-110.789647,31.731446]]]}}, -{"type":"Feature","id":"04025","properties":{"name":"Yavapai"},"geometry":{"type":"Polygon","coordinates":[[[-113.336425,35.526966],[-112.438206,35.258596],[-112.334144,34.973795],[-111.775497,34.979272],[-111.556419,34.469916],[-111.496173,33.998899],[-112.273898,33.883884],[-113.336425,33.998899],[-113.330948,34.316562],[-113.336425,35.526966]]]}}, -{"type":"Feature","id":"04027","properties":{"name":"Yuma"},"geometry":{"type":"Polygon","coordinates":[[[-113.993657,33.462159],[-113.336425,33.380005],[-113.336425,32.503695],[-113.336425,32.038155],[-114.815198,32.492741],[-114.72209,32.717295],[-114.513967,33.029481],[-113.993657,33.462159]]]}}, -{"type":"Feature","id":"05001","properties":{"name":"Arkansas"},"geometry":{"type":"Polygon","coordinates":[[[-91.587494,34.568501],[-91.379371,34.563024],[-91.056231,34.33847],[-91.116477,34.119392],[-91.423186,34.01533],[-91.445094,34.081054],[-91.70251,34.48087],[-91.680602,34.48087],[-91.587494,34.568501]]]}}, -{"type":"Feature","id":"05003","properties":{"name":"Ashley"},"geometry":{"type":"Polygon","coordinates":[[[-91.992788,33.396436],[-91.456048,33.390959],[-91.461525,33.007573],[-92.069465,33.007573],[-92.135188,33.160928],[-91.992788,33.396436]]]}}, -{"type":"Feature","id":"05005","properties":{"name":"Baxter"},"geometry":{"type":"Polygon","coordinates":[[[-92.529528,36.496384],[-92.151619,36.496384],[-92.157096,36.260876],[-92.195435,36.134906],[-92.414512,35.976075],[-92.409035,36.063706],[-92.529528,36.496384]]]}}, -{"type":"Feature","id":"05007","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-94.473842,36.501861],[-94.079502,36.496384],[-93.865902,36.496384],[-93.816609,36.304691],[-93.887809,36.233491],[-94.013779,36.206106],[-94.550519,36.102045],[-94.561473,36.162291],[-94.616242,36.501861],[-94.473842,36.501861]]]}}, -{"type":"Feature","id":"05009","properties":{"name":"Boone"},"geometry":{"type":"Polygon","coordinates":[[[-93.066268,36.496384],[-92.852668,36.496384],[-92.891006,36.112998],[-92.945776,36.112998],[-93.301777,36.123952],[-93.2963,36.496384],[-93.066268,36.496384]]]}}, -{"type":"Feature","id":"05011","properties":{"name":"Bradley"},"geometry":{"type":"Polygon","coordinates":[[[-92.332358,33.708622],[-91.976357,33.703145],[-91.992788,33.396436],[-92.135188,33.160928],[-92.348789,33.297851],[-92.332358,33.708622]]]}}, -{"type":"Feature","id":"05013","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-92.584298,33.80173],[-92.332358,33.796253],[-92.332358,33.708622],[-92.348789,33.297851],[-92.567867,33.369051],[-92.584298,33.80173]]]}}, -{"type":"Feature","id":"05015","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-93.728978,36.496384],[-93.586578,36.496384],[-93.312731,36.496384],[-93.2963,36.496384],[-93.301777,36.123952],[-93.477039,36.123952],[-93.816609,36.304691],[-93.865902,36.496384],[-93.728978,36.496384]]]}}, -{"type":"Feature","id":"05017","properties":{"name":"Chicot"},"geometry":{"type":"Polygon","coordinates":[[[-91.390325,33.560744],[-91.231493,33.560744],[-91.215062,33.527883],[-91.16577,33.01305],[-91.16577,33.002096],[-91.264355,33.007573],[-91.30817,33.007573],[-91.43414,33.007573],[-91.461525,33.007573],[-91.456048,33.390959],[-91.456048,33.566221],[-91.390325,33.560744]]]}}, -{"type":"Feature","id":"05019","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-93.477039,34.33847],[-93.405839,34.33847],[-92.885529,34.157731],[-92.891006,33.807207],[-93.104607,33.779822],[-93.372977,33.955084],[-93.477039,34.33847]]]}}, -{"type":"Feature","id":"05021","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-90.782384,36.496384],[-90.57426,36.496384],[-90.218259,36.496384],[-90.190875,36.200629],[-90.804292,36.266353],[-90.782384,36.496384]]]}}, -{"type":"Feature","id":"05023","properties":{"name":"Cleburne"},"geometry":{"type":"Polygon","coordinates":[[[-91.998265,35.707705],[-91.839434,35.702228],[-91.795618,35.532443],[-92.113281,35.362658],[-92.250204,35.362658],[-92.23925,35.713182],[-91.998265,35.707705]]]}}, -{"type":"Feature","id":"05025","properties":{"name":"Cleveland"},"geometry":{"type":"Polygon","coordinates":[[[-92.058511,34.064623],[-91.954449,34.064623],[-91.976357,33.790776],[-91.976357,33.703145],[-92.332358,33.708622],[-92.332358,33.796253],[-92.337835,34.059146],[-92.233773,34.064623],[-92.058511,34.064623]]]}}, -{"type":"Feature","id":"05027","properties":{"name":"Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-93.247007,33.440252],[-93.115561,33.451205],[-92.978637,33.380005],[-92.989591,33.018527],[-93.236053,33.018527],[-93.487993,33.018527],[-93.3675,33.445728],[-93.247007,33.440252]]]}}, -{"type":"Feature","id":"05029","properties":{"name":"Conway"},"geometry":{"type":"Polygon","coordinates":[[[-92.852668,35.461243],[-92.480236,35.368135],[-92.556913,35.110718],[-93.038884,35.077857],[-92.896483,35.170965],[-92.852668,35.461243]]]}}, -{"type":"Feature","id":"05031","properties":{"name":"Craighead"},"geometry":{"type":"Polygon","coordinates":[[[-90.289459,35.997983],[-90.289459,35.702228],[-90.930262,35.707705],[-91.034323,35.707705],[-91.034323,35.882967],[-90.853584,35.970598],[-90.377091,35.997983],[-90.289459,35.997983]]]}}, -{"type":"Feature","id":"05033","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-93.964486,35.762474],[-93.909717,35.762474],[-94.074025,35.444812],[-94.380734,35.444812],[-94.430026,35.395519],[-94.473842,35.636505],[-94.490273,35.756997],[-93.964486,35.762474]]]}}, -{"type":"Feature","id":"05035","properties":{"name":"Crittenden"},"geometry":{"type":"Polygon","coordinates":[[[-90.50306,35.439335],[-90.289459,35.439335],[-90.141582,35.439335],[-90.075859,35.384565],[-90.311367,34.995703],[-90.30589,34.858779],[-90.409952,34.831394],[-90.409952,34.902595],[-90.50306,35.14358],[-90.50306,35.439335]]]}}, -{"type":"Feature","id":"05037","properties":{"name":"Cross"},"geometry":{"type":"Polygon","coordinates":[[[-90.744046,35.444812],[-90.50306,35.439335],[-90.50306,35.14358],[-90.831677,35.149057],[-91.045277,35.149057],[-91.0398,35.351704],[-91.0398,35.444812],[-90.744046,35.444812]]]}}, -{"type":"Feature","id":"05039","properties":{"name":"Dallas"},"geometry":{"type":"Polygon","coordinates":[[[-92.885529,34.157731],[-92.677405,34.152254],[-92.337835,34.059146],[-92.332358,33.796253],[-92.584298,33.80173],[-92.891006,33.807207],[-92.885529,34.157731]]]}}, -{"type":"Feature","id":"05041","properties":{"name":"Desha"},"geometry":{"type":"Polygon","coordinates":[[[-91.116477,34.119392],[-90.952169,34.119392],[-91.231493,33.560744],[-91.390325,33.560744],[-91.456048,33.566221],[-91.56011,33.785299],[-91.423186,34.01533],[-91.116477,34.119392]]]}}, -{"type":"Feature","id":"05043","properties":{"name":"Drew"},"geometry":{"type":"Polygon","coordinates":[[[-91.664172,33.790776],[-91.56011,33.785299],[-91.456048,33.566221],[-91.456048,33.390959],[-91.992788,33.396436],[-91.976357,33.703145],[-91.976357,33.790776],[-91.664172,33.790776]]]}}, -{"type":"Feature","id":"05045","properties":{"name":"Faulkner"},"geometry":{"type":"Polygon","coordinates":[[[-92.480236,35.368135],[-92.250204,35.362658],[-92.113281,35.362658],[-92.118758,35.066903],[-92.118758,35.012133],[-92.228296,34.957364],[-92.545959,34.951887],[-92.556913,35.110718],[-92.480236,35.368135],[-92.480236,35.368135]]]}}, -{"type":"Feature","id":"05047","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-93.909717,35.762474],[-93.696116,35.767951],[-93.712547,35.373611],[-94.03021,35.21478],[-94.074025,35.444812],[-93.909717,35.762474]]]}}, -{"type":"Feature","id":"05049","properties":{"name":"Fulton"},"geometry":{"type":"Polygon","coordinates":[[[-91.669648,36.501861],[-91.450571,36.496384],[-91.691556,36.255399],[-92.124235,36.260876],[-92.157096,36.260876],[-92.151619,36.496384],[-92.118758,36.496384],[-91.669648,36.501861]]]}}, -{"type":"Feature","id":"05051","properties":{"name":"Garland"},"geometry":{"type":"Polygon","coordinates":[[[-93.285346,34.771148],[-93.077222,34.771148],[-92.792421,34.502778],[-93.405839,34.398716],[-93.394885,34.743763],[-93.285346,34.771148]]]}}, -{"type":"Feature","id":"05053","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-92.392605,34.497301],[-92.244727,34.491824],[-92.206389,34.491824],[-92.233773,34.064623],[-92.337835,34.059146],[-92.677405,34.152254],[-92.666452,34.415147],[-92.392605,34.497301]]]}}, -{"type":"Feature","id":"05055","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-90.804292,36.266353],[-90.190875,36.200629],[-90.377091,35.997983],[-90.853584,35.970598],[-90.809769,36.151337],[-90.804292,36.266353]]]}}, -{"type":"Feature","id":"05057","properties":{"name":"Hempstead"},"geometry":{"type":"Polygon","coordinates":[[[-93.811132,34.009853],[-93.455131,33.955084],[-93.482516,33.47859],[-93.723501,33.484067],[-93.827563,33.610037],[-93.95901,33.752437],[-93.822086,34.009853],[-93.811132,34.009853]]]}}, -{"type":"Feature","id":"05059","properties":{"name":"Hot Spring"},"geometry":{"type":"Polygon","coordinates":[[[-92.792421,34.502778],[-92.666452,34.415147],[-92.677405,34.152254],[-92.885529,34.157731],[-93.405839,34.33847],[-93.405839,34.398716],[-92.792421,34.502778]]]}}, -{"type":"Feature","id":"05061","properties":{"name":"Howard"},"geometry":{"type":"Polygon","coordinates":[[[-94.24381,34.190592],[-93.937102,34.349424],[-93.822086,34.009853],[-93.95901,33.752437],[-93.95901,33.752437],[-94.189041,34.190592],[-94.24381,34.190592]]]}}, -{"type":"Feature","id":"05063","properties":{"name":"Independence"},"geometry":{"type":"Polygon","coordinates":[[[-91.850387,35.866536],[-91.707987,35.943213],[-91.357463,35.888444],[-91.198632,35.888444],[-91.582017,35.532443],[-91.795618,35.532443],[-91.839434,35.702228],[-91.850387,35.866536]]]}}, -{"type":"Feature","id":"05065","properties":{"name":"Izard"},"geometry":{"type":"Polygon","coordinates":[[[-92.124235,36.260876],[-91.691556,36.255399],[-91.707987,35.943213],[-91.850387,35.866536],[-92.195435,36.134906],[-92.157096,36.260876],[-92.124235,36.260876]]]}}, -{"type":"Feature","id":"05067","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-91.198632,35.888444],[-91.034323,35.882967],[-91.034323,35.707705],[-91.0398,35.444812],[-91.0398,35.351704],[-91.346509,35.439335],[-91.582017,35.532443],[-91.198632,35.888444]]]}}, -{"type":"Feature","id":"05069","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-92.069465,34.491824],[-92.031127,34.491824],[-91.70251,34.48087],[-91.445094,34.081054],[-91.603925,34.113915],[-91.954449,34.064623],[-92.058511,34.064623],[-92.233773,34.064623],[-92.206389,34.491824],[-92.069465,34.491824]]]}}, -{"type":"Feature","id":"05071","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-93.696116,35.767951],[-93.520854,35.762474],[-93.164853,35.729613],[-93.2963,35.329796],[-93.422269,35.329796],[-93.712547,35.373611],[-93.696116,35.767951]]]}}, -{"type":"Feature","id":"05073","properties":{"name":"Lafayette"},"geometry":{"type":"Polygon","coordinates":[[[-93.723501,33.484067],[-93.482516,33.47859],[-93.3675,33.445728],[-93.487993,33.018527],[-93.49347,33.018527],[-93.520854,33.018527],[-93.805655,33.018527],[-93.723501,33.484067]]]}}, -{"type":"Feature","id":"05075","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-91.242447,36.255399],[-90.809769,36.151337],[-90.853584,35.970598],[-91.034323,35.882967],[-91.198632,35.888444],[-91.357463,35.888444],[-91.258878,36.255399],[-91.242447,36.255399]]]}}, -{"type":"Feature","id":"05077","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-91.100047,34.869733],[-90.409952,34.902595],[-90.409952,34.831394],[-90.585214,34.639701],[-91.050754,34.645178],[-91.100047,34.869733]]]}}, -{"type":"Feature","id":"05079","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-91.603925,34.113915],[-91.445094,34.081054],[-91.423186,34.01533],[-91.56011,33.785299],[-91.664172,33.790776],[-91.976357,33.790776],[-91.954449,34.064623],[-91.603925,34.113915]]]}}, -{"type":"Feature","id":"05081","properties":{"name":"Little River"},"geometry":{"type":"Polygon","coordinates":[[[-94.446457,33.927699],[-93.95901,33.752437],[-93.95901,33.752437],[-93.827563,33.610037],[-94.041164,33.54979],[-94.484796,33.637421],[-94.479319,33.938653],[-94.446457,33.927699]]]}}, -{"type":"Feature","id":"05083","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-93.422269,35.329796],[-93.2963,35.329796],[-93.279869,35.318842],[-93.70707,35.01761],[-94.139749,35.099764],[-94.03021,35.21478],[-93.712547,35.373611],[-93.422269,35.329796]]]}}, -{"type":"Feature","id":"05085","properties":{"name":"Lonoke"},"geometry":{"type":"Polygon","coordinates":[[[-91.801095,35.028564],[-91.680602,34.48087],[-91.70251,34.48087],[-92.031127,34.491824],[-92.118758,35.012133],[-92.118758,35.066903],[-91.801095,35.028564]]]}}, -{"type":"Feature","id":"05087","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-93.816609,36.304691],[-93.477039,36.123952],[-93.520854,35.762474],[-93.696116,35.767951],[-93.909717,35.762474],[-93.964486,35.762474],[-93.887809,36.233491],[-93.816609,36.304691]]]}}, -{"type":"Feature","id":"05089","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-92.770513,36.496384],[-92.529528,36.496384],[-92.409035,36.063706],[-92.891006,36.112998],[-92.852668,36.496384],[-92.770513,36.496384]]]}}, -{"type":"Feature","id":"05091","properties":{"name":"Miller"},"geometry":{"type":"Polygon","coordinates":[[[-93.827563,33.610037],[-93.723501,33.484067],[-93.805655,33.018527],[-93.816609,33.018527],[-94.041164,33.018527],[-94.041164,33.270466],[-94.041164,33.54979],[-93.827563,33.610037]]]}}, -{"type":"Feature","id":"05093","properties":{"name":"Mississippi"},"geometry":{"type":"Polygon","coordinates":[[[-89.730812,35.997983],[-89.643181,35.904875],[-89.911551,35.53792],[-90.141582,35.439335],[-90.289459,35.439335],[-90.289459,35.702228],[-90.289459,35.997983],[-89.960843,35.997983],[-89.730812,35.997983]]]}}, -{"type":"Feature","id":"05095","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-91.275309,34.984749],[-91.149339,35.00118],[-91.100047,34.869733],[-91.050754,34.645178],[-91.056231,34.33847],[-91.379371,34.563024],[-91.368417,34.913548],[-91.275309,34.984749]]]}}, -{"type":"Feature","id":"05097","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-93.570147,34.743763],[-93.394885,34.743763],[-93.405839,34.398716],[-93.405839,34.33847],[-93.477039,34.33847],[-93.750886,34.349424],[-93.937102,34.349424],[-93.931625,34.667086],[-93.712547,34.743763],[-93.570147,34.743763]]]}}, -{"type":"Feature","id":"05099","properties":{"name":"Nevada"},"geometry":{"type":"Polygon","coordinates":[[[-93.455131,33.955084],[-93.372977,33.955084],[-93.104607,33.779822],[-93.115561,33.451205],[-93.247007,33.440252],[-93.3675,33.445728],[-93.482516,33.47859],[-93.455131,33.955084]]]}}, -{"type":"Feature","id":"05101","properties":{"name":"Newton"},"geometry":{"type":"Polygon","coordinates":[[[-93.301777,36.123952],[-92.945776,36.112998],[-92.951253,35.724136],[-93.016976,35.724136],[-93.164853,35.729613],[-93.520854,35.762474],[-93.477039,36.123952],[-93.301777,36.123952]]]}}, -{"type":"Feature","id":"05103","properties":{"name":"Ouachita"},"geometry":{"type":"Polygon","coordinates":[[[-92.891006,33.807207],[-92.584298,33.80173],[-92.567867,33.369051],[-92.737652,33.385482],[-92.978637,33.380005],[-93.115561,33.451205],[-93.104607,33.779822],[-92.891006,33.807207]]]}}, -{"type":"Feature","id":"05105","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-93.038884,35.077857],[-92.556913,35.110718],[-92.545959,34.951887],[-92.737652,34.853302],[-92.967683,34.858779],[-93.077222,34.771148],[-93.285346,34.771148],[-93.038884,35.077857]]]}}, -{"type":"Feature","id":"05107","properties":{"name":"Phillips"},"geometry":{"type":"Polygon","coordinates":[[[-91.050754,34.645178],[-90.585214,34.639701],[-90.568783,34.524686],[-90.957646,34.119392],[-90.952169,34.119392],[-91.116477,34.119392],[-91.056231,34.33847],[-91.050754,34.645178]]]}}, -{"type":"Feature","id":"05109","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-93.750886,34.349424],[-93.477039,34.33847],[-93.372977,33.955084],[-93.455131,33.955084],[-93.811132,34.009853],[-93.822086,34.009853],[-93.937102,34.349424],[-93.750886,34.349424]]]}}, -{"type":"Feature","id":"05111","properties":{"name":"Poinsett"},"geometry":{"type":"Polygon","coordinates":[[[-90.930262,35.707705],[-90.289459,35.702228],[-90.289459,35.439335],[-90.50306,35.439335],[-90.744046,35.444812],[-91.0398,35.444812],[-91.034323,35.707705],[-90.930262,35.707705]]]}}, -{"type":"Feature","id":"05113","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-94.451934,34.727333],[-93.931625,34.667086],[-93.937102,34.349424],[-94.24381,34.190592],[-94.468365,34.190592],[-94.462888,34.508255],[-94.451934,34.727333]]]}}, -{"type":"Feature","id":"05115","properties":{"name":"Pope"},"geometry":{"type":"Polygon","coordinates":[[[-93.016976,35.724136],[-92.951253,35.724136],[-92.808852,35.724136],[-92.852668,35.461243],[-92.896483,35.170965],[-93.279869,35.318842],[-93.2963,35.329796],[-93.164853,35.729613],[-93.016976,35.724136]]]}}, -{"type":"Feature","id":"05117","properties":{"name":"Prairie"},"geometry":{"type":"Polygon","coordinates":[[[-91.587494,35.023087],[-91.467002,35.088811],[-91.368417,34.913548],[-91.379371,34.563024],[-91.587494,34.568501],[-91.680602,34.48087],[-91.801095,35.028564],[-91.587494,35.023087]]]}}, -{"type":"Feature","id":"05119","properties":{"name":"Pulaski"},"geometry":{"type":"Polygon","coordinates":[[[-92.228296,34.957364],[-92.118758,35.012133],[-92.031127,34.491824],[-92.069465,34.491824],[-92.206389,34.491824],[-92.244727,34.491824],[-92.737652,34.853302],[-92.545959,34.951887],[-92.228296,34.957364]]]}}, -{"type":"Feature","id":"05121","properties":{"name":"Randolph"},"geometry":{"type":"Polygon","coordinates":[[[-90.848107,36.496384],[-90.782384,36.496384],[-90.804292,36.266353],[-90.809769,36.151337],[-91.242447,36.255399],[-91.258878,36.255399],[-91.406755,36.496384],[-91.127431,36.496384],[-90.848107,36.496384]]]}}, -{"type":"Feature","id":"05123","properties":{"name":"St. Francis"},"geometry":{"type":"Polygon","coordinates":[[[-90.831677,35.149057],[-90.50306,35.14358],[-90.409952,34.902595],[-91.100047,34.869733],[-91.149339,35.00118],[-91.045277,35.149057],[-90.831677,35.149057]]]}}, -{"type":"Feature","id":"05125","properties":{"name":"Saline"},"geometry":{"type":"Polygon","coordinates":[[[-92.967683,34.858779],[-92.737652,34.853302],[-92.244727,34.491824],[-92.392605,34.497301],[-92.666452,34.415147],[-92.792421,34.502778],[-93.077222,34.771148],[-92.967683,34.858779]]]}}, -{"type":"Feature","id":"05127","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-94.183564,35.083334],[-94.139749,35.099764],[-93.70707,35.01761],[-93.712547,34.743763],[-93.931625,34.667086],[-94.451934,34.727333],[-94.446457,34.935456],[-94.183564,35.083334]]]}}, -{"type":"Feature","id":"05129","properties":{"name":"Searcy"},"geometry":{"type":"Polygon","coordinates":[[[-92.945776,36.112998],[-92.891006,36.112998],[-92.409035,36.063706],[-92.414512,35.976075],[-92.414512,35.789859],[-92.611682,35.789859],[-92.808852,35.724136],[-92.951253,35.724136],[-92.945776,36.112998]]]}}, -{"type":"Feature","id":"05131","properties":{"name":"Sebastian"},"geometry":{"type":"Polygon","coordinates":[[[-94.380734,35.444812],[-94.074025,35.444812],[-94.03021,35.21478],[-94.139749,35.099764],[-94.183564,35.083334],[-94.446457,34.935456],[-94.430026,35.379088],[-94.430026,35.395519],[-94.380734,35.444812]]]}}, -{"type":"Feature","id":"05133","properties":{"name":"Sevier"},"geometry":{"type":"Polygon","coordinates":[[[-94.189041,34.190592],[-93.95901,33.752437],[-94.446457,33.927699],[-94.479319,33.938653],[-94.468365,34.190592],[-94.24381,34.190592],[-94.189041,34.190592]]]}}, -{"type":"Feature","id":"05135","properties":{"name":"Sharp"},"geometry":{"type":"Polygon","coordinates":[[[-91.450571,36.496384],[-91.406755,36.496384],[-91.258878,36.255399],[-91.357463,35.888444],[-91.707987,35.943213],[-91.691556,36.255399],[-91.450571,36.496384],[-91.450571,36.496384]]]}}, -{"type":"Feature","id":"05137","properties":{"name":"Stone"},"geometry":{"type":"Polygon","coordinates":[[[-92.195435,36.134906],[-91.850387,35.866536],[-91.839434,35.702228],[-91.998265,35.707705],[-92.23925,35.713182],[-92.414512,35.789859],[-92.414512,35.976075],[-92.195435,36.134906]]]}}, -{"type":"Feature","id":"05139","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-92.737652,33.385482],[-92.567867,33.369051],[-92.348789,33.297851],[-92.135188,33.160928],[-92.069465,33.007573],[-92.710267,33.01305],[-92.726698,33.01305],[-92.989591,33.018527],[-92.978637,33.380005],[-92.737652,33.385482]]]}}, -{"type":"Feature","id":"05141","properties":{"name":"Van Buren"},"geometry":{"type":"Polygon","coordinates":[[[-92.611682,35.789859],[-92.414512,35.789859],[-92.23925,35.713182],[-92.250204,35.362658],[-92.480236,35.368135],[-92.480236,35.368135],[-92.852668,35.461243],[-92.808852,35.724136],[-92.611682,35.789859]]]}}, -{"type":"Feature","id":"05143","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-94.013779,36.206106],[-93.887809,36.233491],[-93.964486,35.762474],[-94.490273,35.756997],[-94.550519,36.102045],[-94.013779,36.206106]]]}}, -{"type":"Feature","id":"05145","properties":{"name":"White"},"geometry":{"type":"Polygon","coordinates":[[[-91.795618,35.532443],[-91.582017,35.532443],[-91.346509,35.439335],[-91.467002,35.088811],[-91.587494,35.023087],[-91.801095,35.028564],[-92.118758,35.066903],[-92.113281,35.362658],[-91.795618,35.532443]]]}}, -{"type":"Feature","id":"05147","properties":{"name":"Woodruff"},"geometry":{"type":"Polygon","coordinates":[[[-91.346509,35.439335],[-91.0398,35.351704],[-91.045277,35.149057],[-91.149339,35.00118],[-91.275309,34.984749],[-91.368417,34.913548],[-91.467002,35.088811],[-91.346509,35.439335]]]}}, -{"type":"Feature","id":"05149","properties":{"name":"Yell"},"geometry":{"type":"Polygon","coordinates":[[[-93.279869,35.318842],[-92.896483,35.170965],[-93.038884,35.077857],[-93.285346,34.771148],[-93.394885,34.743763],[-93.570147,34.743763],[-93.712547,34.743763],[-93.70707,35.01761],[-93.279869,35.318842]]]}}, -{"type":"Feature","id":"06001","properties":{"name":"Alameda"},"geometry":{"type":"Polygon","coordinates":[[[-122.269314,37.903958],[-121.557312,37.821804],[-121.469681,37.482234],[-121.475158,37.482234],[-121.853067,37.482234],[-122.083098,37.476757],[-122.11596,37.504141],[-122.31313,37.898481],[-122.269314,37.903958]]]}}, -{"type":"Feature","id":"06003","properties":{"name":"Alpine"},"geometry":{"type":"Polygon","coordinates":[[[-119.585614,38.714545],[-119.640383,38.325682],[-120.018292,38.435221],[-120.073061,38.506421],[-120.073061,38.511898],[-120.073061,38.698114],[-120.073061,38.703591],[-119.903276,38.933623],[-119.585614,38.714545]]]}}, -{"type":"Feature","id":"06005","properties":{"name":"Amador"},"geometry":{"type":"Polygon","coordinates":[[[-120.073061,38.698114],[-120.073061,38.511898],[-120.993187,38.227097],[-121.026049,38.298298],[-121.026049,38.506421],[-120.073061,38.703591],[-120.073061,38.698114]]]}}, -{"type":"Feature","id":"06007","properties":{"name":"Butte"},"geometry":{"type":"Polygon","coordinates":[[[-121.584697,40.100211],[-121.436819,40.149503],[-121.075341,39.596333],[-121.623035,39.295101],[-121.907836,39.306055],[-121.891405,39.382732],[-122.04476,39.798979],[-121.584697,40.100211]]]}}, -{"type":"Feature","id":"06009","properties":{"name":"Calaveras"},"geometry":{"type":"Polygon","coordinates":[[[-120.073061,38.506421],[-120.018292,38.435221],[-120.045677,38.424267],[-120.653617,37.832758],[-120.927464,38.07922],[-120.993187,38.227097],[-120.073061,38.511898],[-120.073061,38.506421]]]}}, -{"type":"Feature","id":"06011","properties":{"name":"Colusa"},"geometry":{"type":"Polygon","coordinates":[[[-122.077621,39.415593],[-121.891405,39.382732],[-121.907836,39.306055],[-121.836636,38.922669],[-122.061191,38.928146],[-122.340515,38.922669],[-122.740331,39.382732],[-122.077621,39.415593]]]}}, -{"type":"Feature","id":"06013","properties":{"name":"Contra Costa"},"geometry":{"type":"Polygon","coordinates":[[[-121.628512,38.101128],[-121.57922,38.095651],[-121.557312,37.821804],[-122.269314,37.903958],[-122.31313,37.898481],[-122.269314,38.062789],[-121.864021,38.068266],[-121.628512,38.101128]]]}}, -{"type":"Feature","id":"06015","properties":{"name":"Del Norte"},"geometry":{"type":"Polygon","coordinates":[[[-124.213628,42.000709],[-123.819288,41.995232],[-123.518057,42.000709],[-123.660457,41.381815],[-124.054797,41.463969],[-124.065751,41.463969],[-124.213628,42.000709]]]}}, -{"type":"Feature","id":"06017","properties":{"name":"El Dorado"},"geometry":{"type":"Polygon","coordinates":[[[-120.001861,39.065069],[-119.903276,38.933623],[-120.073061,38.703591],[-121.026049,38.506421],[-121.141065,38.714545],[-121.04248,38.917192],[-120.001861,39.065069]]]}}, -{"type":"Feature","id":"06019","properties":{"name":"Fresno"},"geometry":{"type":"Polygon","coordinates":[[[-119.021489,37.586295],[-118.775026,37.460326],[-118.358779,36.742847],[-118.98315,36.742847],[-119.57466,36.490907],[-119.958045,36.403276],[-120.314047,35.904875],[-120.681002,36.266353],[-120.91651,36.742847],[-120.544078,37.044078],[-120.281185,36.764754],[-119.821122,36.846908],[-119.021489,37.586295]]]}}, -{"type":"Feature","id":"06021","properties":{"name":"Glenn"},"geometry":{"type":"Polygon","coordinates":[[[-122.937501,39.798979],[-122.04476,39.798979],[-121.891405,39.382732],[-122.077621,39.415593],[-122.740331,39.382732],[-122.882732,39.579902],[-122.937501,39.798979]]]}}, -{"type":"Feature","id":"06023","properties":{"name":"Humboldt"},"geometry":{"type":"Polygon","coordinates":[[[-124.054797,41.463969],[-123.660457,41.381815],[-123.408518,41.179168],[-123.545441,40.001626],[-124.021935,40.001626],[-124.410798,40.439781],[-124.065751,41.463969],[-124.054797,41.463969]]]}}, -{"type":"Feature","id":"06025","properties":{"name":"Imperial"},"geometry":{"type":"Polygon","coordinates":[[[-114.733044,33.434775],[-114.628982,33.434775],[-114.513967,33.029481],[-114.72209,32.717295],[-116.107756,32.61871],[-116.085849,33.423821],[-114.733044,33.434775]]]}}, -{"type":"Feature","id":"06027","properties":{"name":"Inyo"},"geometry":{"type":"Polygon","coordinates":[[[-117.937054,37.465803],[-117.832993,37.465803],[-117.164806,36.972878],[-115.899633,36.00346],[-115.647693,35.80629],[-117.630346,35.795336],[-118.008255,35.789859],[-118.358779,36.742847],[-118.775026,37.460326],[-117.937054,37.465803]]]}}, -{"type":"Feature","id":"06029","properties":{"name":"Kern"},"geometry":{"type":"Polygon","coordinates":[[[-118.008255,35.789859],[-117.630346,35.795336],[-117.668684,34.820441],[-118.884565,34.793056],[-119.443213,34.902595],[-119.470598,34.902595],[-120.193554,35.789859],[-119.536321,35.789859],[-118.008255,35.789859]]]}}, -{"type":"Feature","id":"06031","properties":{"name":"Kings"},"geometry":{"type":"Polygon","coordinates":[[[-119.57466,36.490907],[-119.536321,35.789859],[-120.193554,35.789859],[-120.215462,35.789859],[-120.314047,35.904875],[-119.958045,36.403276],[-119.57466,36.490907]]]}}, -{"type":"Feature","id":"06033","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-122.882732,39.579902],[-122.740331,39.382732],[-122.340515,38.922669],[-122.395284,38.862422],[-122.625315,38.665253],[-122.822485,38.851469],[-123.090855,39.070546],[-122.882732,39.579902]]]}}, -{"type":"Feature","id":"06035","properties":{"name":"Lassen"},"geometry":{"type":"Polygon","coordinates":[[[-120.943895,41.184645],[-120.001861,41.184645],[-120.001861,39.722302],[-120.149738,39.705871],[-120.209985,40.08378],[-121.119157,40.445258],[-121.327281,40.445258],[-121.332757,41.184645],[-120.943895,41.184645]]]}}, -{"type":"Feature","id":"06037","properties":{"name":"Los Angeles"},"geometry":{"type":"Polygon","coordinates":[[[-117.668684,34.820441],[-117.7837,33.94413],[-118.117793,33.741483],[-118.944811,34.042715],[-118.638103,34.289177],[-118.884565,34.793056],[-117.668684,34.820441]]]}}, -{"type":"Feature","id":"06039","properties":{"name":"Madera"},"geometry":{"type":"Polygon","coordinates":[[[-119.267951,37.73965],[-119.021489,37.586295],[-119.821122,36.846908],[-120.281185,36.764754],[-120.544078,37.044078],[-120.051153,37.181002],[-119.30629,37.777988],[-119.267951,37.73965]]]}}, -{"type":"Feature","id":"06041","properties":{"name":"Marin"},"geometry":{"type":"Polygon","coordinates":[[[-122.844393,38.27639],[-122.488392,38.112082],[-122.504823,37.821804],[-123.014178,38.002543],[-123.003224,38.298298],[-122.844393,38.27639]]]}}, -{"type":"Feature","id":"06043","properties":{"name":"Mariposa"},"geometry":{"type":"Polygon","coordinates":[[[-120.084015,37.827281],[-119.30629,37.777988],[-120.051153,37.181002],[-120.385247,37.635588],[-120.385247,37.635588],[-120.084015,37.827281]]]}}, -{"type":"Feature","id":"06045","properties":{"name":"Mendocino"},"geometry":{"type":"Polygon","coordinates":[[[-124.021935,40.001626],[-123.545441,40.001626],[-122.932024,39.979718],[-122.937501,39.798979],[-122.882732,39.579902],[-123.090855,39.070546],[-122.822485,38.851469],[-123.074425,38.851469],[-123.534488,38.769315],[-123.737134,38.95553],[-124.021935,40.001626]]]}}, -{"type":"Feature","id":"06047","properties":{"name":"Merced"},"geometry":{"type":"Polygon","coordinates":[[[-120.385247,37.635588],[-120.051153,37.181002],[-120.544078,37.044078],[-120.91651,36.742847],[-121.217742,36.961924],[-121.228696,37.137186],[-120.385247,37.635588]]]}}, -{"type":"Feature","id":"06049","properties":{"name":"Modoc"},"geometry":{"type":"Polygon","coordinates":[[[-121.316327,41.995232],[-120.878171,41.995232],[-120.001861,41.995232],[-120.001861,41.184645],[-120.943895,41.184645],[-121.332757,41.184645],[-121.447773,41.184645],[-121.447773,41.995232],[-121.316327,41.995232]]]}}, -{"type":"Feature","id":"06051","properties":{"name":"Mono"},"geometry":{"type":"Polygon","coordinates":[[[-119.585614,38.714545],[-119.328197,38.533806],[-119.158412,38.413313],[-118.429979,37.898481],[-117.832993,37.465803],[-117.937054,37.465803],[-118.775026,37.460326],[-119.021489,37.586295],[-119.267951,37.73965],[-119.640383,38.325682],[-119.585614,38.714545]]]}}, -{"type":"Feature","id":"06053","properties":{"name":"Monterey"},"geometry":{"type":"Polygon","coordinates":[[[-121.699712,36.918109],[-121.644943,36.896201],[-121.31085,36.501861],[-120.681002,36.266353],[-120.314047,35.904875],[-120.215462,35.789859],[-121.343711,35.795336],[-121.896882,36.315645],[-121.809251,36.852385],[-121.699712,36.918109]]]}}, -{"type":"Feature","id":"06055","properties":{"name":"Napa"},"geometry":{"type":"Polygon","coordinates":[[[-122.395284,38.862422],[-122.105006,38.511898],[-122.406238,38.155897],[-122.625315,38.665253],[-122.395284,38.862422]]]}}, -{"type":"Feature","id":"06057","properties":{"name":"Nevada"},"geometry":{"type":"Polygon","coordinates":[[[-120.555032,39.508701],[-120.001861,39.442978],[-120.007338,39.317009],[-120.149738,39.317009],[-121.277988,39.032208],[-121.020572,39.393686],[-120.555032,39.508701]]]}}, -{"type":"Feature","id":"06059","properties":{"name":"Orange"},"geometry":{"type":"Polygon","coordinates":[[[-117.7837,33.94413],[-117.674161,33.87293],[-117.509853,33.505975],[-117.597484,33.385482],[-118.117793,33.741483],[-117.7837,33.94413]]]}}, -{"type":"Feature","id":"06061","properties":{"name":"Placer"},"geometry":{"type":"Polygon","coordinates":[[[-120.149738,39.317009],[-120.007338,39.317009],[-120.001861,39.163654],[-120.001861,39.114362],[-120.001861,39.065069],[-121.04248,38.917192],[-121.141065,38.714545],[-121.486112,38.736453],[-121.414912,38.999346],[-121.277988,39.032208],[-120.149738,39.317009]]]}}, -{"type":"Feature","id":"06063","properties":{"name":"Plumas"},"geometry":{"type":"Polygon","coordinates":[[[-121.119157,40.445258],[-120.209985,40.08378],[-120.149738,39.705871],[-121.009618,39.640148],[-121.075341,39.596333],[-121.436819,40.149503],[-121.497066,40.445258],[-121.327281,40.445258],[-121.119157,40.445258]]]}}, -{"type":"Feature","id":"06065","properties":{"name":"Riverside"},"geometry":{"type":"Polygon","coordinates":[[[-114.733044,34.081054],[-114.43729,34.081054],[-114.628982,33.434775],[-114.733044,33.434775],[-116.085849,33.423821],[-117.476991,33.505975],[-117.509853,33.505975],[-117.674161,33.87293],[-117.559146,34.031761],[-114.733044,34.081054]]]}}, -{"type":"Feature","id":"06067","properties":{"name":"Sacramento"},"geometry":{"type":"Polygon","coordinates":[[[-121.557312,38.736453],[-121.486112,38.736453],[-121.141065,38.714545],[-121.026049,38.506421],[-121.026049,38.298298],[-121.097249,38.287344],[-121.57922,38.095651],[-121.628512,38.101128],[-121.864021,38.068266],[-121.590174,38.314728],[-121.601128,38.736453],[-121.557312,38.736453]]]}}, -{"type":"Feature","id":"06069","properties":{"name":"San Benito"},"geometry":{"type":"Polygon","coordinates":[[[-121.447773,36.989309],[-121.217742,36.961924],[-120.91651,36.742847],[-120.681002,36.266353],[-121.31085,36.501861],[-121.644943,36.896201],[-121.57922,36.901678],[-121.447773,36.989309]]]}}, -{"type":"Feature","id":"06071","properties":{"name":"San Bernardino"},"geometry":{"type":"Polygon","coordinates":[[[-117.630346,35.795336],[-115.647693,35.80629],[-114.634459,35.00118],[-114.136058,34.305608],[-114.43729,34.081054],[-114.733044,34.081054],[-117.559146,34.031761],[-117.674161,33.87293],[-117.7837,33.94413],[-117.668684,34.820441],[-117.630346,35.795336]]]}}, -{"type":"Feature","id":"06073","properties":{"name":"San Diego"},"geometry":{"type":"Polygon","coordinates":[[[-117.476991,33.505975],[-116.085849,33.423821],[-116.107756,32.61871],[-117.126467,32.536556],[-117.597484,33.385482],[-117.509853,33.505975],[-117.476991,33.505975]]]}}, -{"type":"Feature","id":"06075","properties":{"name":"San Francisco"},"geometry":{"type":"Polygon","coordinates":[[[-122.428146,37.706788],[-122.504823,37.706788],[-122.389807,37.706788],[-122.428146,37.706788]]]}}, -{"type":"Feature","id":"06077","properties":{"name":"San Joaquin"},"geometry":{"type":"Polygon","coordinates":[[[-121.097249,38.287344],[-121.026049,38.298298],[-120.993187,38.227097],[-120.927464,38.07922],[-120.921987,37.805373],[-121.469681,37.482234],[-121.557312,37.821804],[-121.57922,38.095651],[-121.097249,38.287344]]]}}, -{"type":"Feature","id":"06079","properties":{"name":"San Luis Obispo"},"geometry":{"type":"Polygon","coordinates":[[[-121.343711,35.795336],[-120.215462,35.789859],[-120.193554,35.789859],[-119.470598,34.902595],[-120.094969,35.116195],[-120.64814,34.973795],[-121.343711,35.795336]]]}}, -{"type":"Feature","id":"06081","properties":{"name":"San Mateo"},"geometry":{"type":"Polygon","coordinates":[[[-122.428146,37.706788],[-122.389807,37.706788],[-122.11596,37.504141],[-122.083098,37.476757],[-122.154299,37.285064],[-122.291222,37.109802],[-122.504823,37.706788],[-122.428146,37.706788]]]}}, -{"type":"Feature","id":"06083","properties":{"name":"Santa Barbara"},"geometry":{"type":"Polygon","coordinates":[[[-120.094969,35.116195],[-119.470598,34.902595],[-119.443213,34.902595],[-119.476075,34.376808],[-120.64814,34.579455],[-120.64814,34.973795],[-120.094969,35.116195]]]}}, -{"type":"Feature","id":"06085","properties":{"name":"Santa Clara"},"geometry":{"type":"Polygon","coordinates":[[[-121.853067,37.482234],[-121.475158,37.482234],[-121.228696,37.137186],[-121.217742,36.961924],[-121.447773,36.989309],[-121.57922,36.901678],[-122.154299,37.285064],[-122.083098,37.476757],[-121.853067,37.482234]]]}}, -{"type":"Feature","id":"06087","properties":{"name":"Santa Cruz"},"geometry":{"type":"Polygon","coordinates":[[[-122.154299,37.285064],[-121.57922,36.901678],[-121.644943,36.896201],[-121.699712,36.918109],[-121.809251,36.852385],[-122.291222,37.109802],[-122.154299,37.285064]]]}}, -{"type":"Feature","id":"06089","properties":{"name":"Shasta"},"geometry":{"type":"Polygon","coordinates":[[[-121.447773,41.184645],[-121.332757,41.184645],[-121.327281,40.445258],[-121.497066,40.445258],[-123.063471,40.286427],[-122.691039,40.576705],[-122.499346,41.184645],[-121.447773,41.184645]]]}}, -{"type":"Feature","id":"06091","properties":{"name":"Sierra"},"geometry":{"type":"Polygon","coordinates":[[[-120.149738,39.705871],[-120.001861,39.722302],[-120.001861,39.442978],[-120.555032,39.508701],[-121.020572,39.393686],[-121.009618,39.640148],[-120.149738,39.705871]]]}}, -{"type":"Feature","id":"06093","properties":{"name":"Siskiyou"},"geometry":{"type":"Polygon","coordinates":[[[-123.233256,42.006186],[-122.291222,42.006186],[-121.447773,41.995232],[-121.447773,41.184645],[-122.499346,41.184645],[-122.586977,41.35443],[-122.915593,40.992952],[-123.408518,41.179168],[-123.660457,41.381815],[-123.518057,42.000709],[-123.233256,42.006186]]]}}, -{"type":"Feature","id":"06095","properties":{"name":"Solano"},"geometry":{"type":"Polygon","coordinates":[[[-121.738051,38.539283],[-121.590174,38.314728],[-121.864021,38.068266],[-122.269314,38.062789],[-122.406238,38.15042],[-122.406238,38.155897],[-122.105006,38.511898],[-121.738051,38.539283]]]}}, -{"type":"Feature","id":"06097","properties":{"name":"Sonoma"},"geometry":{"type":"Polygon","coordinates":[[[-123.074425,38.851469],[-122.822485,38.851469],[-122.625315,38.665253],[-122.406238,38.155897],[-122.406238,38.15042],[-122.488392,38.112082],[-122.844393,38.27639],[-123.003224,38.298298],[-123.534488,38.769315],[-123.074425,38.851469]]]}}, -{"type":"Feature","id":"06099","properties":{"name":"Stanislaus"},"geometry":{"type":"Polygon","coordinates":[[[-120.921987,37.805373],[-120.927464,38.07922],[-120.653617,37.832758],[-120.385247,37.635588],[-120.385247,37.635588],[-121.228696,37.137186],[-121.475158,37.482234],[-121.469681,37.482234],[-120.921987,37.805373]]]}}, -{"type":"Feature","id":"06101","properties":{"name":"Sutter"},"geometry":{"type":"Polygon","coordinates":[[[-121.623035,39.295101],[-121.414912,38.999346],[-121.486112,38.736453],[-121.557312,38.736453],[-121.601128,38.736453],[-121.836636,38.922669],[-121.907836,39.306055],[-121.623035,39.295101]]]}}, -{"type":"Feature","id":"06103","properties":{"name":"Tehama"},"geometry":{"type":"Polygon","coordinates":[[[-121.497066,40.445258],[-121.436819,40.149503],[-121.584697,40.100211],[-122.04476,39.798979],[-122.937501,39.798979],[-122.932024,39.979718],[-123.063471,40.286427],[-121.497066,40.445258]]]}}, -{"type":"Feature","id":"06105","properties":{"name":"Trinity"},"geometry":{"type":"Polygon","coordinates":[[[-122.586977,41.35443],[-122.499346,41.184645],[-122.691039,40.576705],[-123.063471,40.286427],[-122.932024,39.979718],[-123.545441,40.001626],[-123.408518,41.179168],[-122.915593,40.992952],[-122.586977,41.35443]]]}}, -{"type":"Feature","id":"06107","properties":{"name":"Tulare"},"geometry":{"type":"Polygon","coordinates":[[[-118.358779,36.742847],[-118.008255,35.789859],[-119.536321,35.789859],[-119.57466,36.490907],[-118.98315,36.742847],[-118.358779,36.742847]]]}}, -{"type":"Feature","id":"06109","properties":{"name":"Tuolumne"},"geometry":{"type":"Polygon","coordinates":[[[-120.045677,38.424267],[-120.018292,38.435221],[-119.640383,38.325682],[-119.267951,37.73965],[-119.30629,37.777988],[-120.084015,37.827281],[-120.385247,37.635588],[-120.653617,37.832758],[-120.045677,38.424267]]]}}, -{"type":"Feature","id":"06111","properties":{"name":"Ventura"},"geometry":{"type":"Polygon","coordinates":[[[-119.443213,34.902595],[-118.884565,34.793056],[-118.638103,34.289177],[-118.944811,34.042715],[-119.476075,34.376808],[-119.443213,34.902595]]]}}, -{"type":"Feature","id":"06113","properties":{"name":"Yolo"},"geometry":{"type":"Polygon","coordinates":[[[-122.061191,38.928146],[-121.836636,38.922669],[-121.601128,38.736453],[-121.590174,38.314728],[-121.738051,38.539283],[-122.105006,38.511898],[-122.395284,38.862422],[-122.340515,38.922669],[-122.061191,38.928146]]]}}, -{"type":"Feature","id":"06115","properties":{"name":"Yuba"},"geometry":{"type":"Polygon","coordinates":[[[-121.075341,39.596333],[-121.009618,39.640148],[-121.020572,39.393686],[-121.277988,39.032208],[-121.414912,38.999346],[-121.623035,39.295101],[-121.075341,39.596333]]]}}, -{"type":"Feature","id":"08001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-103.795594,40.001626],[-103.707963,40.001626],[-103.707963,39.738733],[-104.830736,39.738733],[-104.885506,39.738733],[-104.704767,39.903041],[-105.055291,39.793502],[-105.055291,39.913995],[-105.055291,40.001626],[-104.151596,40.001626],[-103.795594,40.001626]]]}}, -{"type":"Feature","id":"08003","properties":{"name":"Alamosa"},"geometry":{"type":"Polygon","coordinates":[[[-105.707047,37.750604],[-105.455107,37.750604],[-105.487969,37.575342],[-105.745385,37.356264],[-106.04114,37.400079],[-106.04114,37.750604],[-105.707047,37.750604]]]}}, -{"type":"Feature","id":"08005","properties":{"name":"Arapahoe"},"geometry":{"type":"Polygon","coordinates":[[[-104.830736,39.738733],[-103.707963,39.738733],[-103.707963,39.568948],[-103.71344,39.568948],[-104.195411,39.563471],[-104.660951,39.563471],[-104.989567,39.568948],[-105.049814,39.563471],[-105.055291,39.623717],[-105.055291,39.629194],[-105.055291,39.629194],[-104.885506,39.738733],[-104.830736,39.738733]]]}}, -{"type":"Feature","id":"08007","properties":{"name":"Archuleta"},"geometry":{"type":"Polygon","coordinates":[[[-107.131051,37.421987],[-106.709327,37.405556],[-106.676465,37.405556],[-106.473818,36.994786],[-107.421329,37.000263],[-107.481575,37.000263],[-107.481575,37.421987],[-107.131051,37.421987]]]}}, -{"type":"Feature","id":"08009","properties":{"name":"Baca"},"geometry":{"type":"Polygon","coordinates":[[[-102.749499,37.641065],[-102.042974,37.646542],[-102.042974,37.389126],[-102.042974,36.994786],[-103.001438,37.000263],[-103.083592,37.000263],[-103.078115,37.641065],[-102.749499,37.641065]]]}}, -{"type":"Feature","id":"08011","properties":{"name":"Bent"},"geometry":{"type":"Polygon","coordinates":[[[-102.744022,38.265436],[-102.749499,37.641065],[-103.078115,37.641065],[-103.406732,37.641065],[-103.401255,38.265436],[-102.744022,38.265436]]]}}, -{"type":"Feature","id":"08013","properties":{"name":"Boulder"},"geometry":{"type":"Polygon","coordinates":[[[-105.340092,40.259042],[-105.055291,40.264519],[-105.055291,40.001626],[-105.055291,39.913995],[-105.055291,39.913995],[-105.400338,39.913995],[-105.674185,39.930426],[-105.652277,40.259042],[-105.340092,40.259042]]]}}, -{"type":"Feature","id":"08015","properties":{"name":"Chaffee"},"geometry":{"type":"Polygon","coordinates":[[[-106.375233,39.054115],[-106.189017,39.054115],[-105.96994,38.692637],[-106.008278,38.446175],[-106.249264,38.424267],[-106.599788,38.999346],[-106.57788,39.059592],[-106.375233,39.054115]]]}}, -{"type":"Feature","id":"08017","properties":{"name":"Cheyenne"},"geometry":{"type":"Polygon","coordinates":[[[-102.04845,39.048638],[-102.042974,38.698114],[-102.042974,38.61596],[-103.171223,38.610483],[-103.165746,39.037685],[-102.04845,39.048638]]]}}, -{"type":"Feature","id":"08019","properties":{"name":"Clear Creek"},"geometry":{"type":"Polygon","coordinates":[[[-105.926124,39.700394],[-105.690616,39.853749],[-105.400338,39.749687],[-105.400338,39.563471],[-105.827539,39.563471],[-105.926124,39.700394]]]}}, -{"type":"Feature","id":"08021","properties":{"name":"Conejos"},"geometry":{"type":"Polygon","coordinates":[[[-106.523111,37.400079],[-106.04114,37.400079],[-105.745385,37.356264],[-105.718001,36.994786],[-106.008278,36.994786],[-106.473818,36.994786],[-106.676465,37.405556],[-106.523111,37.400079]]]}}, -{"type":"Feature","id":"08023","properties":{"name":"Costilla"},"geometry":{"type":"Polygon","coordinates":[[[-105.23603,37.624634],[-105.153876,37.290541],[-105.153876,36.994786],[-105.219599,36.994786],[-105.718001,36.994786],[-105.745385,37.356264],[-105.487969,37.575342],[-105.23603,37.624634]]]}}, -{"type":"Feature","id":"08025","properties":{"name":"Crowley"},"geometry":{"type":"Polygon","coordinates":[[[-104.053011,38.522852],[-103.505317,38.517375],[-103.49984,38.265436],[-104.058488,38.144943],[-104.053011,38.522852]]]}}, -{"type":"Feature","id":"08027","properties":{"name":"Custer"},"geometry":{"type":"Polygon","coordinates":[[[-105.794678,38.265436],[-105.049814,38.259959],[-105.049814,37.914912],[-105.186737,38.00802],[-105.471538,37.898481],[-105.794678,38.265436]]]}}, -{"type":"Feature","id":"08029","properties":{"name":"Delta"},"geometry":{"type":"Polygon","coordinates":[[[-107.514437,39.212947],[-107.503483,39.218424],[-107.498006,38.67073],[-108.001885,38.67073],[-108.379794,38.67073],[-107.514437,39.212947]]]}}, -{"type":"Feature","id":"08031","properties":{"name":"Denver"},"geometry":{"type":"Polygon","coordinates":[[[-104.704767,39.903041],[-104.885506,39.738733],[-105.055291,39.629194],[-105.055291,39.629194],[-105.055291,39.623717],[-105.055291,39.793502],[-104.704767,39.903041]]]}}, -{"type":"Feature","id":"08033","properties":{"name":"Dolores"},"geometry":{"type":"Polygon","coordinates":[[[-109.042503,37.88205],[-107.859484,37.777988],[-107.9745,37.641065],[-109.042503,37.482234],[-109.042503,37.88205]]]}}, -{"type":"Feature","id":"08035","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-104.989567,39.568948],[-104.660951,39.563471],[-104.660951,39.130793],[-104.995044,39.130793],[-105.033383,39.130793],[-105.329138,39.130793],[-105.049814,39.563471],[-104.989567,39.568948]]]}}, -{"type":"Feature","id":"08037","properties":{"name":"Eagle"},"geometry":{"type":"Polygon","coordinates":[[[-106.627173,39.924949],[-106.43548,39.924949],[-106.205448,39.377255],[-106.424526,39.360824],[-107.04342,39.366301],[-107.11462,39.366301],[-107.032466,39.919472],[-106.627173,39.924949]]]}}, -{"type":"Feature","id":"08039","properties":{"name":"Elbert"},"geometry":{"type":"Polygon","coordinates":[[[-104.195411,39.563471],[-103.71344,39.568948],[-103.718917,38.867899],[-104.053011,38.867899],[-104.053011,39.130793],[-104.660951,39.130793],[-104.660951,39.563471],[-104.195411,39.563471]]]}}, -{"type":"Feature","id":"08041","properties":{"name":"El Paso"},"geometry":{"type":"Polygon","coordinates":[[[-104.995044,39.130793],[-104.660951,39.130793],[-104.053011,39.130793],[-104.053011,38.867899],[-104.053011,38.522852],[-104.940275,38.517375],[-104.940275,38.648822],[-105.033383,39.130793],[-104.995044,39.130793]]]}}, -{"type":"Feature","id":"08043","properties":{"name":"Fremont"},"geometry":{"type":"Polygon","coordinates":[[[-105.329138,38.698114],[-104.940275,38.648822],[-104.940275,38.517375],[-105.049814,38.259959],[-105.794678,38.265436],[-106.008278,38.446175],[-105.96994,38.692637],[-105.329138,38.698114]]]}}, -{"type":"Feature","id":"08045","properties":{"name":"Garfield"},"geometry":{"type":"Polygon","coordinates":[[[-107.037943,40.089257],[-107.032466,39.919472],[-107.11462,39.366301],[-107.432283,39.366301],[-108.774133,39.366301],[-109.053457,39.366301],[-109.053457,39.497748],[-109.053457,39.662056],[-107.936161,39.694917],[-107.037943,40.089257]]]}}, -{"type":"Feature","id":"08047","properties":{"name":"Gilpin"},"geometry":{"type":"Polygon","coordinates":[[[-105.674185,39.930426],[-105.400338,39.913995],[-105.400338,39.749687],[-105.690616,39.853749],[-105.674185,39.930426]]]}}, -{"type":"Feature","id":"08049","properties":{"name":"Grand"},"geometry":{"type":"Polygon","coordinates":[[[-105.854924,40.483597],[-105.652277,40.259042],[-105.674185,39.930426],[-105.690616,39.853749],[-105.926124,39.700394],[-106.43548,39.924949],[-106.627173,39.924949],[-106.654557,40.445258],[-105.854924,40.483597]]]}}, -{"type":"Feature","id":"08051","properties":{"name":"Gunnison"},"geometry":{"type":"Polygon","coordinates":[[[-107.503483,39.218424],[-107.393944,39.256762],[-106.599788,38.999346],[-106.249264,38.424267],[-106.999605,38.424267],[-106.999605,38.144943],[-107.569206,38.144943],[-107.63493,38.303775],[-107.498006,38.67073],[-107.503483,39.218424]]]}}, -{"type":"Feature","id":"08053","properties":{"name":"Hinsdale"},"geometry":{"type":"Polygon","coordinates":[[[-106.999605,38.144943],[-106.999605,37.958727],[-107.103666,37.95325],[-107.131051,37.421987],[-107.481575,37.421987],[-107.481575,37.641065],[-107.569206,37.964204],[-107.569206,38.144943],[-106.999605,38.144943]]]}}, -{"type":"Feature","id":"08055","properties":{"name":"Huerfano"},"geometry":{"type":"Polygon","coordinates":[[[-105.186737,38.00802],[-105.049814,37.914912],[-104.348765,37.816327],[-105.153876,37.290541],[-105.23603,37.624634],[-105.487969,37.575342],[-105.455107,37.750604],[-105.471538,37.898481],[-105.186737,38.00802]]]}}, -{"type":"Feature","id":"08057","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-106.857204,41.003906],[-106.320464,40.998429],[-106.189017,40.998429],[-105.854924,40.483597],[-106.654557,40.445258],[-106.857204,41.003906]]]}}, -{"type":"Feature","id":"08059","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-105.055291,39.913995],[-105.055291,39.913995],[-105.055291,39.793502],[-105.055291,39.623717],[-105.049814,39.563471],[-105.329138,39.130793],[-105.329138,39.130793],[-105.400338,39.563471],[-105.400338,39.749687],[-105.400338,39.913995],[-105.055291,39.913995]]]}}, -{"type":"Feature","id":"08061","properties":{"name":"Kiowa"},"geometry":{"type":"Polygon","coordinates":[[[-102.042974,38.61596],[-102.042974,38.270913],[-102.212759,38.265436],[-102.744022,38.265436],[-103.401255,38.265436],[-103.49984,38.265436],[-103.505317,38.517375],[-103.171223,38.610483],[-102.042974,38.61596]]]}}, -{"type":"Feature","id":"08063","properties":{"name":"Kit Carson"},"geometry":{"type":"Polygon","coordinates":[[[-102.426359,39.568948],[-102.04845,39.574425],[-102.04845,39.568948],[-102.04845,39.130793],[-102.04845,39.048638],[-103.165746,39.037685],[-103.154792,39.563471],[-102.804268,39.568948],[-102.426359,39.568948]]]}}, -{"type":"Feature","id":"08065","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-106.134248,39.377255],[-106.189017,39.054115],[-106.375233,39.054115],[-106.57788,39.059592],[-106.424526,39.360824],[-106.205448,39.377255],[-106.134248,39.377255]]]}}, -{"type":"Feature","id":"08067","properties":{"name":"La Plata"},"geometry":{"type":"Polygon","coordinates":[[[-107.804715,37.641065],[-107.481575,37.641065],[-107.481575,37.421987],[-107.481575,37.000263],[-108.379794,37.000263],[-107.9745,37.641065],[-107.804715,37.641065]]]}}, -{"type":"Feature","id":"08069","properties":{"name":"Larimer"},"geometry":{"type":"Polygon","coordinates":[[[-105.279845,40.998429],[-104.945752,40.998429],[-105.055291,40.264519],[-105.340092,40.259042],[-105.652277,40.259042],[-105.854924,40.483597],[-106.189017,40.998429],[-105.279845,40.998429]]]}}, -{"type":"Feature","id":"08071","properties":{"name":"Las Animas"},"geometry":{"type":"Polygon","coordinates":[[[-104.348765,37.816327],[-104.058488,37.734173],[-103.406732,37.641065],[-103.078115,37.641065],[-103.083592,37.000263],[-104.009195,36.994786],[-105.153876,36.994786],[-105.153876,37.290541],[-104.348765,37.816327]]]}}, -{"type":"Feature","id":"08073","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-103.71344,39.568948],[-103.707963,39.568948],[-103.154792,39.563471],[-103.165746,39.037685],[-103.171223,38.610483],[-103.505317,38.517375],[-104.053011,38.522852],[-104.053011,38.867899],[-103.718917,38.867899],[-103.71344,39.568948]]]}}, -{"type":"Feature","id":"08075","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-102.650914,41.003906],[-102.650914,40.751967],[-102.667345,40.439781],[-102.78236,40.439781],[-103.466978,40.434304],[-103.581994,40.521935],[-103.576517,41.003906],[-103.384824,41.003906],[-102.650914,41.003906]]]}}, -{"type":"Feature","id":"08077","properties":{"name":"Mesa"},"geometry":{"type":"Polygon","coordinates":[[[-108.774133,39.366301],[-107.432283,39.366301],[-107.393944,39.256762],[-107.503483,39.218424],[-107.514437,39.212947],[-108.379794,38.67073],[-109.058934,38.500944],[-109.053457,39.366301],[-108.774133,39.366301]]]}}, -{"type":"Feature","id":"08079","properties":{"name":"Mineral"},"geometry":{"type":"Polygon","coordinates":[[[-107.103666,37.95325],[-106.999605,37.958727],[-106.692896,37.832758],[-106.709327,37.405556],[-107.131051,37.421987],[-107.103666,37.95325]]]}}, -{"type":"Feature","id":"08081","properties":{"name":"Moffat"},"geometry":{"type":"Polygon","coordinates":[[[-107.919731,41.003906],[-107.317267,41.003906],[-107.43776,40.220704],[-109.053457,40.220704],[-109.04798,40.653382],[-109.04798,40.998429],[-107.919731,41.003906]]]}}, -{"type":"Feature","id":"08083","properties":{"name":"Montezuma"},"geometry":{"type":"Polygon","coordinates":[[[-107.9745,37.641065],[-108.379794,37.000263],[-109.042503,37.000263],[-109.042503,37.482234],[-107.9745,37.641065]]]}}, -{"type":"Feature","id":"08085","properties":{"name":"Montrose"},"geometry":{"type":"Polygon","coordinates":[[[-108.001885,38.67073],[-107.498006,38.67073],[-107.63493,38.303775],[-107.963546,38.15042],[-109.042503,38.15042],[-109.058934,38.500944],[-108.379794,38.67073],[-108.001885,38.67073]]]}}, -{"type":"Feature","id":"08087","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-104.091349,40.521935],[-103.581994,40.521935],[-103.466978,40.434304],[-103.707963,40.001626],[-103.795594,40.001626],[-104.151596,40.001626],[-104.091349,40.521935]]]}}, -{"type":"Feature","id":"08089","properties":{"name":"Otero"},"geometry":{"type":"Polygon","coordinates":[[[-103.401255,38.265436],[-103.406732,37.641065],[-104.058488,37.734173],[-104.058488,38.144943],[-103.49984,38.265436],[-103.401255,38.265436]]]}}, -{"type":"Feature","id":"08091","properties":{"name":"Ouray"},"geometry":{"type":"Polygon","coordinates":[[[-107.63493,38.303775],[-107.569206,38.144943],[-107.569206,37.964204],[-107.738991,37.903958],[-107.963546,38.15042],[-107.63493,38.303775]]]}}, -{"type":"Feature","id":"08093","properties":{"name":"Park"},"geometry":{"type":"Polygon","coordinates":[[[-105.827539,39.563471],[-105.400338,39.563471],[-105.329138,39.130793],[-105.329138,38.698114],[-105.96994,38.692637],[-106.189017,39.054115],[-106.134248,39.377255],[-105.827539,39.563471]]]}}, -{"type":"Feature","id":"08095","properties":{"name":"Phillips"},"geometry":{"type":"Polygon","coordinates":[[[-102.327774,40.74649],[-102.053927,40.751967],[-102.053927,40.697198],[-102.053927,40.439781],[-102.426359,40.439781],[-102.667345,40.439781],[-102.650914,40.751967],[-102.327774,40.74649]]]}}, -{"type":"Feature","id":"08097","properties":{"name":"Pitkin"},"geometry":{"type":"Polygon","coordinates":[[[-107.04342,39.366301],[-106.424526,39.360824],[-106.57788,39.059592],[-106.599788,38.999346],[-107.393944,39.256762],[-107.432283,39.366301],[-107.11462,39.366301],[-107.04342,39.366301]]]}}, -{"type":"Feature","id":"08099","properties":{"name":"Prowers"},"geometry":{"type":"Polygon","coordinates":[[[-102.212759,38.265436],[-102.042974,38.270913],[-102.042974,38.259959],[-102.042974,37.73965],[-102.042974,37.646542],[-102.749499,37.641065],[-102.744022,38.265436],[-102.212759,38.265436]]]}}, -{"type":"Feature","id":"08101","properties":{"name":"Pueblo"},"geometry":{"type":"Polygon","coordinates":[[[-104.053011,38.522852],[-104.058488,38.144943],[-104.058488,37.734173],[-104.348765,37.816327],[-105.049814,37.914912],[-105.049814,38.259959],[-104.940275,38.517375],[-104.053011,38.522852]]]}}, -{"type":"Feature","id":"08103","properties":{"name":"Rio Blanco"},"geometry":{"type":"Polygon","coordinates":[[[-107.109143,40.226181],[-107.037943,40.089257],[-107.936161,39.694917],[-109.053457,39.662056],[-109.053457,40.220704],[-107.43776,40.220704],[-107.109143,40.226181]]]}}, -{"type":"Feature","id":"08105","properties":{"name":"Rio Grande"},"geometry":{"type":"Polygon","coordinates":[[[-106.692896,37.832758],[-106.04114,37.750604],[-106.04114,37.400079],[-106.523111,37.400079],[-106.676465,37.405556],[-106.709327,37.405556],[-106.692896,37.832758]]]}}, -{"type":"Feature","id":"08107","properties":{"name":"Routt"},"geometry":{"type":"Polygon","coordinates":[[[-107.317267,41.003906],[-106.857204,41.003906],[-106.654557,40.445258],[-106.627173,39.924949],[-107.032466,39.919472],[-107.037943,40.089257],[-107.109143,40.226181],[-107.43776,40.220704],[-107.317267,41.003906]]]}}, -{"type":"Feature","id":"08109","properties":{"name":"Saguache"},"geometry":{"type":"Polygon","coordinates":[[[-106.008278,38.446175],[-105.794678,38.265436],[-105.471538,37.898481],[-105.455107,37.750604],[-105.707047,37.750604],[-106.04114,37.750604],[-106.692896,37.832758],[-106.999605,37.958727],[-106.999605,38.144943],[-106.999605,38.424267],[-106.249264,38.424267],[-106.008278,38.446175]]]}}, -{"type":"Feature","id":"08111","properties":{"name":"San Juan"},"geometry":{"type":"Polygon","coordinates":[[[-107.569206,37.964204],[-107.481575,37.641065],[-107.804715,37.641065],[-107.9745,37.641065],[-107.859484,37.777988],[-107.738991,37.903958],[-107.569206,37.964204]]]}}, -{"type":"Feature","id":"08113","properties":{"name":"San Miguel"},"geometry":{"type":"Polygon","coordinates":[[[-109.042503,38.15042],[-107.963546,38.15042],[-107.738991,37.903958],[-107.859484,37.777988],[-109.042503,37.88205],[-109.042503,38.15042]]]}}, -{"type":"Feature","id":"08115","properties":{"name":"Sedgwick"},"geometry":{"type":"Polygon","coordinates":[[[-102.623529,41.003906],[-102.053927,41.003906],[-102.053927,40.751967],[-102.327774,40.74649],[-102.650914,40.751967],[-102.650914,41.003906],[-102.623529,41.003906]]]}}, -{"type":"Feature","id":"08117","properties":{"name":"Summit"},"geometry":{"type":"Polygon","coordinates":[[[-106.43548,39.924949],[-105.926124,39.700394],[-105.827539,39.563471],[-106.134248,39.377255],[-106.205448,39.377255],[-106.43548,39.924949]]]}}, -{"type":"Feature","id":"08119","properties":{"name":"Teller"},"geometry":{"type":"Polygon","coordinates":[[[-105.329138,39.130793],[-105.329138,39.130793],[-105.033383,39.130793],[-104.940275,38.648822],[-105.329138,38.698114],[-105.329138,39.130793]]]}}, -{"type":"Feature","id":"08121","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-102.78236,40.439781],[-102.804268,39.568948],[-103.154792,39.563471],[-103.707963,39.568948],[-103.707963,39.738733],[-103.707963,40.001626],[-103.466978,40.434304],[-102.78236,40.439781]]]}}, -{"type":"Feature","id":"08123","properties":{"name":"Weld"},"geometry":{"type":"Polygon","coordinates":[[[-103.576517,41.003906],[-103.581994,40.521935],[-104.091349,40.521935],[-104.151596,40.001626],[-105.055291,40.001626],[-105.055291,40.264519],[-104.945752,40.998429],[-104.053011,41.003906],[-103.576517,41.003906]]]}}, -{"type":"Feature","id":"08125","properties":{"name":"Yuma"},"geometry":{"type":"Polygon","coordinates":[[[-102.426359,40.439781],[-102.053927,40.439781],[-102.053927,40.346673],[-102.053927,40.001626],[-102.04845,39.574425],[-102.426359,39.568948],[-102.804268,39.568948],[-102.78236,40.439781],[-102.667345,40.439781],[-102.426359,40.439781]]]}}, -{"type":"Feature","id":"09001","properties":{"name":"Fairfield"},"geometry":{"type":"Polygon","coordinates":[[[-73.519068,41.666616],[-73.310944,41.469446],[-73.108298,41.168214],[-73.655992,40.987475],[-73.546453,41.365384],[-73.530022,41.529692],[-73.519068,41.666616]]]}}, -{"type":"Feature","id":"09003","properties":{"name":"Hartford"},"geometry":{"type":"Polygon","coordinates":[[[-73.009713,42.039048],[-72.511311,42.033571],[-72.412726,41.600893],[-72.467496,41.584462],[-72.544173,41.644708],[-72.752296,41.578985],[-72.949466,41.644708],[-72.982328,41.639231],[-73.009713,42.039048]]]}}, -{"type":"Feature","id":"09005","properties":{"name":"Litchfield"},"geometry":{"type":"Polygon","coordinates":[[[-73.053528,42.039048],[-73.009713,42.039048],[-72.982328,41.639231],[-73.310944,41.469446],[-73.519068,41.666616],[-73.486206,42.050002],[-73.053528,42.039048]]]}}, -{"type":"Feature","id":"09007","properties":{"name":"Middlesex"},"geometry":{"type":"Polygon","coordinates":[[[-72.544173,41.644708],[-72.467496,41.584462],[-72.341526,41.277753],[-72.538696,41.255845],[-72.752296,41.578985],[-72.544173,41.644708]]]}}, -{"type":"Feature","id":"09009","properties":{"name":"New Haven"},"geometry":{"type":"Polygon","coordinates":[[[-72.949466,41.644708],[-72.752296,41.578985],[-72.538696,41.255845],[-73.108298,41.168214],[-73.310944,41.469446],[-72.982328,41.639231],[-72.949466,41.644708]]]}}, -{"type":"Feature","id":"09011","properties":{"name":"New London"},"geometry":{"type":"Polygon","coordinates":[[[-72.237464,41.715908],[-71.788355,41.639231],[-71.788355,41.595416],[-71.859555,41.321569],[-72.341526,41.277753],[-72.467496,41.584462],[-72.412726,41.600893],[-72.237464,41.715908]]]}}, -{"type":"Feature","id":"09013","properties":{"name":"Tolland"},"geometry":{"type":"Polygon","coordinates":[[[-72.133402,42.028094],[-72.100541,42.028094],[-72.237464,41.715908],[-72.412726,41.600893],[-72.511311,42.033571],[-72.133402,42.028094]]]}}, -{"type":"Feature","id":"09015","properties":{"name":"Windham"},"geometry":{"type":"Polygon","coordinates":[[[-71.799309,42.006186],[-71.788355,41.726862],[-71.788355,41.639231],[-72.237464,41.715908],[-72.100541,42.028094],[-71.799309,42.006186]]]}}, -{"type":"Feature","id":"10001","properties":{"name":"Kent"},"geometry":{"type":"Polygon","coordinates":[[[-75.616736,39.311532],[-75.512674,39.366301],[-75.310028,38.944577],[-75.720798,38.829561],[-75.748183,39.141746],[-75.75366,39.245808],[-75.759137,39.295101],[-75.616736,39.311532]]]}}, -{"type":"Feature","id":"10003","properties":{"name":"New Castle"},"geometry":{"type":"Polygon","coordinates":[[[-75.414089,39.804456],[-75.446951,39.771595],[-75.507197,39.683964],[-75.512674,39.366301],[-75.616736,39.311532],[-75.759137,39.295101],[-75.764614,39.377255],[-75.786521,39.722302],[-75.594828,39.837318],[-75.594828,39.837318],[-75.578398,39.837318],[-75.414089,39.804456]]]}}, -{"type":"Feature","id":"10005","properties":{"name":"Sussex"},"geometry":{"type":"Polygon","coordinates":[[[-75.047134,38.451652],[-75.342889,38.451652],[-75.69889,38.561191],[-75.709844,38.637868],[-75.720798,38.829561],[-75.310028,38.944577],[-75.047134,38.451652]]]}}, -{"type":"Feature","id":"11001","properties":{"name":"District of Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-77.035264,38.993869],[-77.002402,38.966484],[-77.040741,38.791222],[-77.046218,38.840515],[-77.117418,38.933623],[-77.035264,38.993869]]]}}, -{"type":"Feature","id":"12001","properties":{"name":"Alachua"},"geometry":{"type":"Polygon","coordinates":[[[-82.506727,29.940487],[-82.419096,29.924056],[-82.052141,29.715932],[-82.057618,29.46947],[-82.408142,29.485901],[-82.654605,29.562578],[-82.660082,29.830948],[-82.528635,29.940487],[-82.506727,29.940487]]]}}, -{"type":"Feature","id":"12003","properties":{"name":"Baker"},"geometry":{"type":"Polygon","coordinates":[[[-82.419096,30.581289],[-82.216449,30.570335],[-82.052141,30.362211],[-82.046664,30.27458],[-82.052141,30.186949],[-82.052141,30.143133],[-82.145249,30.143133],[-82.298603,30.143133],[-82.457435,30.137656],[-82.457435,30.586766],[-82.419096,30.581289]]]}}, -{"type":"Feature","id":"12005","properties":{"name":"Bay"},"geometry":{"type":"Polygon","coordinates":[[[-85.382121,30.564858],[-85.387598,30.20338],[-85.387598,29.924056],[-85.995538,30.269103],[-85.990061,30.389596],[-85.43689,30.570335],[-85.382121,30.564858]]]}}, -{"type":"Feature","id":"12007","properties":{"name":"Bradford"},"geometry":{"type":"Polygon","coordinates":[[[-82.145249,30.143133],[-82.052141,30.143133],[-82.046664,29.715932],[-82.052141,29.715932],[-82.419096,29.924056],[-82.145249,30.143133]]]}}, -{"type":"Feature","id":"12009","properties":{"name":"Brevard"},"geometry":{"type":"Polygon","coordinates":[[[-80.447398,27.859249],[-80.869122,27.820911],[-80.863645,28.346697],[-80.989615,28.615067],[-80.732199,28.790329],[-80.447398,27.859249]]]}}, -{"type":"Feature","id":"12011","properties":{"name":"Broward"},"geometry":{"type":"Polygon","coordinates":[[[-80.250228,26.33666],[-80.074966,26.320229],[-80.118781,25.975182],[-80.874599,25.980659],[-80.880076,26.259983],[-80.880076,26.331183],[-80.250228,26.33666]]]}}, -{"type":"Feature","id":"12013","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-85.16852,30.608673],[-84.933012,30.608673],[-85.113751,30.197903],[-85.22329,30.20338],[-85.387598,30.20338],[-85.382121,30.564858],[-85.16852,30.608673]]]}}, -{"type":"Feature","id":"12015","properties":{"name":"Charlotte"},"geometry":{"type":"Polygon","coordinates":[[[-82.041187,27.032231],[-81.564693,27.032231],[-81.564693,26.769338],[-82.063095,26.769338],[-82.210972,26.774815],[-82.23288,26.780292],[-82.23288,26.785769],[-82.271219,26.791246],[-82.375281,26.9446],[-82.057618,27.032231],[-82.041187,27.032231]]]}}, -{"type":"Feature","id":"12017","properties":{"name":"Citrus"},"geometry":{"type":"Polygon","coordinates":[[[-82.523158,29.042268],[-82.309557,28.960114],[-82.265742,28.669836],[-82.649128,28.691744],[-82.758666,28.992976],[-82.534112,29.042268],[-82.523158,29.042268]]]}}, -{"type":"Feature","id":"12019","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-81.701617,30.192426],[-81.679709,30.121226],[-81.581124,29.841902],[-82.046664,29.715932],[-82.052141,30.143133],[-82.052141,30.186949],[-81.701617,30.192426]]]}}, -{"type":"Feature","id":"12021","properties":{"name":"Collier"},"geometry":{"type":"Polygon","coordinates":[[[-81.564693,26.511922],[-80.880076,26.259983],[-80.874599,25.980659],[-80.874599,25.805397],[-81.345616,25.805397],[-81.679709,25.843735],[-81.844017,26.331183],[-81.564693,26.511922]]]}}, -{"type":"Feature","id":"12023","properties":{"name":"Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-82.69842,30.597719],[-82.687466,30.597719],[-82.583404,30.592243],[-82.457435,30.586766],[-82.457435,30.137656],[-82.528635,29.940487],[-82.660082,29.830948],[-82.802482,29.93501],[-82.797005,30.334826],[-82.69842,30.597719]]]}}, -{"type":"Feature","id":"12027","properties":{"name":"DeSoto"},"geometry":{"type":"Polygon","coordinates":[[[-81.581124,27.33894],[-81.564693,27.33894],[-81.564693,27.032231],[-82.041187,27.032231],[-82.057618,27.032231],[-82.057618,27.207493],[-82.057618,27.33894],[-81.581124,27.33894]]]}}, -{"type":"Feature","id":"12029","properties":{"name":"Dixie"},"geometry":{"type":"Polygon","coordinates":[[[-82.939406,29.825471],[-82.922975,29.825471],[-82.939406,29.589962],[-83.16396,29.288731],[-83.410422,29.66664],[-83.317314,29.819994],[-82.939406,29.825471]]]}}, -{"type":"Feature","id":"12031","properties":{"name":"Duval"},"geometry":{"type":"Polygon","coordinates":[[[-81.608509,30.586766],[-81.444201,30.510088],[-81.378478,30.252672],[-81.389431,30.252672],[-81.679709,30.121226],[-81.701617,30.192426],[-82.052141,30.186949],[-82.046664,30.27458],[-81.608509,30.586766]]]}}, -{"type":"Feature","id":"12033","properties":{"name":"Escambia"},"geometry":{"type":"Polygon","coordinates":[[[-87.249758,30.997536],[-87.162127,30.997536],[-87.310004,30.734643],[-86.921141,30.373165],[-87.518128,30.280057],[-87.600282,30.997536],[-87.249758,30.997536]]]}}, -{"type":"Feature","id":"12035","properties":{"name":"Flagler"},"geometry":{"type":"Polygon","coordinates":[[[-81.214169,29.672117],[-81.214169,29.672117],[-81.10463,29.425654],[-81.110107,29.425654],[-81.433247,29.39827],[-81.526355,29.622824],[-81.214169,29.672117]]]}}, -{"type":"Feature","id":"12037","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-85.004212,30.011687],[-84.544149,30.011687],[-84.341502,29.962394],[-85.217813,29.694024],[-85.02612,29.973348],[-85.004212,30.011687]]]}}, -{"type":"Feature","id":"12039","properties":{"name":"Gadsden"},"geometry":{"type":"Polygon","coordinates":[[[-84.867289,30.712735],[-84.861812,30.712735],[-84.379841,30.690827],[-84.281256,30.685351],[-84.648211,30.389596],[-84.933012,30.608673],[-84.867289,30.712735]]]}}, -{"type":"Feature","id":"12041","properties":{"name":"Gilchrist"},"geometry":{"type":"Polygon","coordinates":[[[-82.879159,29.885717],[-82.802482,29.93501],[-82.660082,29.830948],[-82.654605,29.562578],[-82.873682,29.589962],[-82.939406,29.589962],[-82.922975,29.825471],[-82.917498,29.825471],[-82.906544,29.825471],[-82.879159,29.885717]]]}}, -{"type":"Feature","id":"12043","properties":{"name":"Glades"},"geometry":{"type":"Polygon","coordinates":[[[-80.945799,27.21297],[-80.885553,26.961031],[-80.96223,26.769338],[-81.564693,26.769338],[-81.564693,27.032231],[-80.945799,27.21297]]]}}, -{"type":"Feature","id":"12045","properties":{"name":"Gulf"},"geometry":{"type":"Polygon","coordinates":[[[-85.22329,30.20338],[-85.113751,30.197903],[-85.02612,29.973348],[-85.217813,29.694024],[-85.387598,29.924056],[-85.387598,30.20338],[-85.22329,30.20338]]]}}, -{"type":"Feature","id":"12047","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-83.311837,30.636058],[-83.136575,30.625104],[-82.687466,30.597719],[-82.69842,30.597719],[-82.797005,30.334826],[-83.081806,30.438888],[-83.169437,30.384119],[-83.311837,30.636058]]]}}, -{"type":"Feature","id":"12049","properties":{"name":"Hardee"},"geometry":{"type":"Polygon","coordinates":[[[-82.052141,27.645649],[-81.564693,27.645649],[-81.564693,27.33894],[-81.581124,27.33894],[-82.057618,27.33894],[-82.052141,27.645649]]]}}, -{"type":"Feature","id":"12051","properties":{"name":"Hendry"},"geometry":{"type":"Polygon","coordinates":[[[-80.96223,26.769338],[-80.885553,26.961031],[-80.880076,26.331183],[-80.880076,26.259983],[-81.564693,26.511922],[-81.564693,26.769338],[-80.96223,26.769338]]]}}, -{"type":"Feature","id":"12053","properties":{"name":"Hernando"},"geometry":{"type":"Polygon","coordinates":[[[-82.265742,28.669836],[-82.057618,28.478144],[-82.254788,28.478144],[-82.676512,28.434328],[-82.649128,28.691744],[-82.265742,28.669836]]]}}, -{"type":"Feature","id":"12055","properties":{"name":"Highlands"},"geometry":{"type":"Polygon","coordinates":[[[-81.49897,27.645649],[-81.142969,27.645649],[-80.945799,27.21297],[-81.564693,27.032231],[-81.564693,27.33894],[-81.564693,27.645649],[-81.49897,27.645649]]]}}, -{"type":"Feature","id":"12057","properties":{"name":"Hillsborough"},"geometry":{"type":"Polygon","coordinates":[[[-82.649128,28.171435],[-82.106911,28.171435],[-82.052141,27.645649],[-82.28765,27.645649],[-82.55602,27.645649],[-82.649128,27.968788],[-82.649128,28.171435]]]}}, -{"type":"Feature","id":"12059","properties":{"name":"Holmes"},"geometry":{"type":"Polygon","coordinates":[[[-86.033877,30.992059],[-85.497137,30.997536],[-85.601199,30.833228],[-85.842184,30.701781],[-86.033877,30.992059]]]}}, -{"type":"Feature","id":"12061","properties":{"name":"Indian River"},"geometry":{"type":"Polygon","coordinates":[[[-80.321428,27.558018],[-80.677429,27.558018],[-80.792445,27.645649],[-80.874599,27.640172],[-80.869122,27.820911],[-80.447398,27.859249],[-80.321428,27.558018]]]}}, -{"type":"Feature","id":"12063","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-85.486183,30.997536],[-85.004212,31.003013],[-84.867289,30.712735],[-84.933012,30.608673],[-85.16852,30.608673],[-85.382121,30.564858],[-85.43689,30.570335],[-85.601199,30.833228],[-85.497137,30.997536],[-85.486183,30.997536]]]}}, -{"type":"Feature","id":"12065","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-83.744516,30.657966],[-83.613069,30.652489],[-83.821193,30.301965],[-83.990978,30.082887],[-84.078609,30.093841],[-84.073132,30.27458],[-84.007409,30.674397],[-83.744516,30.657966]]]}}, -{"type":"Feature","id":"12067","properties":{"name":"Lafayette"},"geometry":{"type":"Polygon","coordinates":[[[-83.246114,30.258149],[-82.879159,29.885717],[-82.906544,29.825471],[-82.917498,29.825471],[-82.922975,29.825471],[-82.939406,29.825471],[-83.317314,29.819994],[-83.366607,30.258149],[-83.246114,30.258149]]]}}, -{"type":"Feature","id":"12069","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-81.641371,29.277777],[-81.367524,28.87796],[-81.411339,28.784852],[-81.542786,28.784852],[-81.657801,28.346697],[-81.959033,28.346697],[-81.953556,28.960114],[-81.641371,29.277777]]]}}, -{"type":"Feature","id":"12071","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-82.063095,26.769338],[-81.564693,26.769338],[-81.564693,26.511922],[-81.844017,26.331183],[-82.063095,26.769338]]]}}, -{"type":"Feature","id":"12073","properties":{"name":"Leon"},"geometry":{"type":"Polygon","coordinates":[[[-84.084086,30.674397],[-84.007409,30.674397],[-84.073132,30.27458],[-84.303164,30.301965],[-84.713934,30.301965],[-84.648211,30.389596],[-84.281256,30.685351],[-84.084086,30.674397]]]}}, -{"type":"Feature","id":"12075","properties":{"name":"Levy"},"geometry":{"type":"Polygon","coordinates":[[[-82.873682,29.589962],[-82.654605,29.562578],[-82.408142,29.485901],[-82.534112,29.042268],[-82.758666,28.992976],[-83.16396,29.288731],[-82.939406,29.589962],[-82.873682,29.589962]]]}}, -{"type":"Feature","id":"12077","properties":{"name":"Liberty"},"geometry":{"type":"Polygon","coordinates":[[[-84.933012,30.608673],[-84.648211,30.389596],[-84.713934,30.301965],[-84.544149,30.011687],[-85.004212,30.011687],[-85.02612,29.973348],[-85.113751,30.197903],[-84.933012,30.608673]]]}}, -{"type":"Feature","id":"12079","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-83.355653,30.636058],[-83.311837,30.636058],[-83.169437,30.384119],[-83.246114,30.258149],[-83.366607,30.258149],[-83.509007,30.301965],[-83.821193,30.301965],[-83.613069,30.652489],[-83.355653,30.636058]]]}}, -{"type":"Feature","id":"12081","properties":{"name":"Manatee"},"geometry":{"type":"Polygon","coordinates":[[[-82.28765,27.645649],[-82.052141,27.645649],[-82.057618,27.33894],[-82.057618,27.207493],[-82.62722,27.388232],[-82.643651,27.388232],[-82.55602,27.645649],[-82.28765,27.645649]]]}}, -{"type":"Feature","id":"12083","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-81.844017,29.518762],[-81.679709,29.327069],[-81.641371,29.277777],[-81.953556,28.960114],[-82.013803,28.960114],[-82.309557,28.960114],[-82.523158,29.042268],[-82.534112,29.042268],[-82.408142,29.485901],[-82.057618,29.46947],[-81.844017,29.518762]]]}}, -{"type":"Feature","id":"12085","properties":{"name":"Martin"},"geometry":{"type":"Polygon","coordinates":[[[-80.080443,26.971985],[-80.885553,26.961031],[-80.677429,27.207493],[-80.200935,27.262263],[-80.080443,26.971985]]]}}, -{"type":"Feature","id":"12086","properties":{"name":"Miami-Dade"},"geometry":{"type":"Polygon","coordinates":[[[-80.874599,25.980659],[-80.118781,25.975182],[-80.304997,25.383672],[-80.858168,25.175549],[-80.874599,25.805397],[-80.874599,25.980659]]]}}, -{"type":"Feature","id":"12087","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-80.874599,25.805397],[-80.858168,25.175549],[-81.077246,25.120779],[-81.345616,25.805397],[-80.874599,25.805397]]]}}, -{"type":"Feature","id":"12089","properties":{"name":"Nassau"},"geometry":{"type":"Polygon","coordinates":[[[-81.904264,30.816797],[-81.444201,30.707258],[-81.444201,30.510088],[-81.608509,30.586766],[-82.046664,30.27458],[-82.052141,30.362211],[-81.904264,30.816797]]]}}, -{"type":"Feature","id":"12091","properties":{"name":"Okaloosa"},"geometry":{"type":"Polygon","coordinates":[[[-86.685633,30.992059],[-86.389878,30.992059],[-86.395355,30.378642],[-86.800648,30.384119],[-86.784218,30.997536],[-86.685633,30.992059]]]}}, -{"type":"Feature","id":"12093","properties":{"name":"Okeechobee"},"geometry":{"type":"Polygon","coordinates":[[[-80.792445,27.645649],[-80.677429,27.558018],[-80.677429,27.207493],[-80.885553,26.961031],[-80.945799,27.21297],[-81.142969,27.645649],[-80.874599,27.640172],[-80.792445,27.645649]]]}}, -{"type":"Feature","id":"12095","properties":{"name":"Orange"},"geometry":{"type":"Polygon","coordinates":[[[-81.542786,28.784852],[-81.411339,28.784852],[-80.989615,28.615067],[-80.863645,28.346697],[-81.2306,28.346697],[-81.657801,28.346697],[-81.542786,28.784852]]]}}, -{"type":"Feature","id":"12097","properties":{"name":"Osceola"},"geometry":{"type":"Polygon","coordinates":[[[-81.2306,28.346697],[-80.863645,28.346697],[-80.869122,27.820911],[-80.874599,27.640172],[-81.142969,27.645649],[-81.657801,28.346697],[-81.2306,28.346697]]]}}, -{"type":"Feature","id":"12099","properties":{"name":"Palm Beach"},"geometry":{"type":"Polygon","coordinates":[[[-80.885553,26.961031],[-80.080443,26.971985],[-80.074966,26.320229],[-80.250228,26.33666],[-80.880076,26.331183],[-80.885553,26.961031]]]}}, -{"type":"Feature","id":"12101","properties":{"name":"Pasco"},"geometry":{"type":"Polygon","coordinates":[[[-82.254788,28.478144],[-82.057618,28.478144],[-82.057618,28.313835],[-82.106911,28.171435],[-82.649128,28.171435],[-82.802482,28.171435],[-82.676512,28.434328],[-82.254788,28.478144]]]}}, -{"type":"Feature","id":"12103","properties":{"name":"Pinellas"},"geometry":{"type":"Polygon","coordinates":[[[-82.649128,28.171435],[-82.649128,27.968788],[-82.802482,28.171435],[-82.649128,28.171435]]]}}, -{"type":"Feature","id":"12105","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-81.657801,28.346697],[-81.142969,27.645649],[-81.49897,27.645649],[-81.564693,27.645649],[-82.052141,27.645649],[-82.106911,28.171435],[-82.057618,28.313835],[-81.959033,28.346697],[-81.657801,28.346697]]]}}, -{"type":"Feature","id":"12107","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-81.581124,29.841902],[-81.526355,29.622824],[-81.433247,29.39827],[-81.679709,29.327069],[-81.844017,29.518762],[-82.057618,29.46947],[-82.052141,29.715932],[-82.046664,29.715932],[-81.581124,29.841902]]]}}, -{"type":"Feature","id":"12109","properties":{"name":"St. Johns"},"geometry":{"type":"Polygon","coordinates":[[[-81.389431,30.252672],[-81.378478,30.252672],[-81.214169,29.672117],[-81.214169,29.672117],[-81.526355,29.622824],[-81.581124,29.841902],[-81.679709,30.121226],[-81.389431,30.252672]]]}}, -{"type":"Feature","id":"12111","properties":{"name":"St. Lucie"},"geometry":{"type":"Polygon","coordinates":[[[-80.677429,27.558018],[-80.321428,27.558018],[-80.200935,27.262263],[-80.677429,27.207493],[-80.677429,27.558018]]]}}, -{"type":"Feature","id":"12113","properties":{"name":"Santa Rosa"},"geometry":{"type":"Polygon","coordinates":[[[-87.162127,30.997536],[-86.784218,30.997536],[-86.800648,30.384119],[-86.921141,30.373165],[-87.310004,30.734643],[-87.162127,30.997536]]]}}, -{"type":"Feature","id":"12115","properties":{"name":"Sarasota"},"geometry":{"type":"Polygon","coordinates":[[[-82.62722,27.388232],[-82.057618,27.207493],[-82.057618,27.032231],[-82.375281,26.9446],[-82.643651,27.388232],[-82.62722,27.388232]]]}}, -{"type":"Feature","id":"12117","properties":{"name":"Seminole"},"geometry":{"type":"Polygon","coordinates":[[[-81.411339,28.784852],[-81.367524,28.87796],[-80.989615,28.615067],[-81.411339,28.784852]]]}}, -{"type":"Feature","id":"12119","properties":{"name":"Sumter"},"geometry":{"type":"Polygon","coordinates":[[[-82.013803,28.960114],[-81.953556,28.960114],[-81.959033,28.346697],[-82.057618,28.313835],[-82.057618,28.478144],[-82.265742,28.669836],[-82.309557,28.960114],[-82.013803,28.960114]]]}}, -{"type":"Feature","id":"12121","properties":{"name":"Suwannee"},"geometry":{"type":"Polygon","coordinates":[[[-83.081806,30.438888],[-82.797005,30.334826],[-82.802482,29.93501],[-82.879159,29.885717],[-83.246114,30.258149],[-83.169437,30.384119],[-83.081806,30.438888]]]}}, -{"type":"Feature","id":"12123","properties":{"name":"Taylor"},"geometry":{"type":"Polygon","coordinates":[[[-83.509007,30.301965],[-83.366607,30.258149],[-83.317314,29.819994],[-83.410422,29.66664],[-83.990978,30.082887],[-83.821193,30.301965],[-83.509007,30.301965]]]}}, -{"type":"Feature","id":"12125","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-82.298603,30.143133],[-82.145249,30.143133],[-82.419096,29.924056],[-82.506727,29.940487],[-82.528635,29.940487],[-82.457435,30.137656],[-82.298603,30.143133]]]}}, -{"type":"Feature","id":"12127","properties":{"name":"Volusia"},"geometry":{"type":"Polygon","coordinates":[[[-81.110107,29.425654],[-81.10463,29.425654],[-80.732199,28.790329],[-80.989615,28.615067],[-81.367524,28.87796],[-81.641371,29.277777],[-81.679709,29.327069],[-81.433247,29.39827],[-81.110107,29.425654]]]}}, -{"type":"Feature","id":"12129","properties":{"name":"Wakulla"},"geometry":{"type":"Polygon","coordinates":[[[-84.303164,30.301965],[-84.073132,30.27458],[-84.078609,30.093841],[-84.341502,29.962394],[-84.544149,30.011687],[-84.713934,30.301965],[-84.303164,30.301965]]]}}, -{"type":"Feature","id":"12131","properties":{"name":"Walton"},"geometry":{"type":"Polygon","coordinates":[[[-86.389878,30.992059],[-86.187231,30.992059],[-86.033877,30.992059],[-85.842184,30.701781],[-85.990061,30.389596],[-85.995538,30.269103],[-86.395355,30.378642],[-86.389878,30.992059]]]}}, -{"type":"Feature","id":"12133","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-85.601199,30.833228],[-85.43689,30.570335],[-85.990061,30.389596],[-85.842184,30.701781],[-85.601199,30.833228]]]}}, -{"type":"Feature","id":"13001","properties":{"name":"Appling"},"geometry":{"type":"Polygon","coordinates":[[[-82.43005,31.966955],[-82.227403,31.912185],[-82.046664,31.824554],[-82.134295,31.632861],[-82.134295,31.468553],[-82.227403,31.528799],[-82.523158,31.709538],[-82.43005,31.966955]]]}}, -{"type":"Feature","id":"13003","properties":{"name":"Atkinson"},"geometry":{"type":"Polygon","coordinates":[[[-83.142052,31.419261],[-82.62722,31.364491],[-82.671035,31.183752],[-82.972267,31.183752],[-83.032514,31.183752],[-83.048944,31.183752],[-83.142052,31.419261]]]}}, -{"type":"Feature","id":"13005","properties":{"name":"Bacon"},"geometry":{"type":"Polygon","coordinates":[[[-82.523158,31.709538],[-82.227403,31.528799],[-82.419096,31.419261],[-82.473866,31.419261],[-82.599835,31.468553],[-82.62722,31.6712],[-82.523158,31.709538]]]}}, -{"type":"Feature","id":"13007","properties":{"name":"Baker"},"geometry":{"type":"Polygon","coordinates":[[[-84.429133,31.435691],[-84.138855,31.441168],[-84.50581,31.07969],[-84.544149,31.07969],[-84.642734,31.260429],[-84.637257,31.435691],[-84.429133,31.435691]]]}}, -{"type":"Feature","id":"13009","properties":{"name":"Baldwin"},"geometry":{"type":"Polygon","coordinates":[[[-83.273499,33.188312],[-83.054421,33.078773],[-83.076329,32.947327],[-83.355653,32.925419],[-83.426853,33.182835],[-83.273499,33.188312]]]}}, -{"type":"Feature","id":"13011","properties":{"name":"Banks"},"geometry":{"type":"Polygon","coordinates":[[[-83.552823,34.486347],[-83.459715,34.48087],[-83.399469,34.458962],[-83.355653,34.223454],[-83.404945,34.196069],[-83.618546,34.289177],[-83.618546,34.294654],[-83.613069,34.431578],[-83.552823,34.486347]]]}}, -{"type":"Feature","id":"13013","properties":{"name":"Barrow"},"geometry":{"type":"Polygon","coordinates":[[[-83.799285,33.927699],[-83.815716,34.124869],[-83.536392,33.966038],[-83.645931,33.905791],[-83.799285,33.927699]]]}}, -{"type":"Feature","id":"13015","properties":{"name":"Bartow"},"geometry":{"type":"Polygon","coordinates":[[[-84.933012,34.398716],[-84.653688,34.415147],[-84.659165,34.075577],[-84.735842,34.081054],[-84.922058,34.081054],[-85.048028,34.097484],[-85.004212,34.393239],[-84.933012,34.398716]]]}}, -{"type":"Feature","id":"13017","properties":{"name":"Ben Hill"},"geometry":{"type":"Polygon","coordinates":[[[-83.481623,31.846462],[-83.180391,31.846462],[-82.994175,31.780739],[-82.999652,31.6712],[-83.454238,31.758831],[-83.481623,31.846462]]]}}, -{"type":"Feature","id":"13019","properties":{"name":"Berrien"},"geometry":{"type":"Polygon","coordinates":[[[-83.240637,31.47403],[-83.147529,31.47403],[-83.142052,31.419261],[-83.048944,31.183752],[-83.196822,31.024921],[-83.295407,31.024921],[-83.43233,31.34806],[-83.339222,31.47403],[-83.240637,31.47403]]]}}, -{"type":"Feature","id":"13021","properties":{"name":"Bibb"},"geometry":{"type":"Polygon","coordinates":[[[-83.722608,32.952804],[-83.711654,32.952804],[-83.514484,32.843265],[-83.596638,32.662526],[-83.7007,32.689911],[-83.892393,32.848742],[-83.722608,32.952804]]]}}, -{"type":"Feature","id":"13023","properties":{"name":"Bleckley"},"geometry":{"type":"Polygon","coordinates":[[[-83.224206,32.585849],[-83.136575,32.421541],[-83.344699,32.273663],[-83.498053,32.399633],[-83.498053,32.454402],[-83.224206,32.585849]]]}}, -{"type":"Feature","id":"13025","properties":{"name":"Brantley"},"geometry":{"type":"Polygon","coordinates":[[[-82.041187,31.369968],[-82.041187,31.375445],[-81.729002,31.331629],[-81.76734,31.167321],[-81.937125,31.046829],[-81.986418,31.057782],[-82.134295,31.00849],[-82.282173,31.227568],[-82.041187,31.369968]]]}}, -{"type":"Feature","id":"13027","properties":{"name":"Brooks"},"geometry":{"type":"Polygon","coordinates":[[[-83.498053,31.052306],[-83.476146,31.030398],[-83.355653,30.636058],[-83.613069,30.652489],[-83.744516,30.657966],[-83.739039,31.035875],[-83.574731,31.07969],[-83.498053,31.052306]]]}}, -{"type":"Feature","id":"13029","properties":{"name":"Bryan"},"geometry":{"type":"Polygon","coordinates":[[[-81.42777,32.235325],[-81.389431,32.098401],[-81.153923,31.725969],[-81.197738,31.725969],[-81.707094,32.087447],[-81.718048,32.087447],[-81.783771,32.153171],[-81.433247,32.240802],[-81.42777,32.235325]]]}}, -{"type":"Feature","id":"13031","properties":{"name":"Bulloch"},"geometry":{"type":"Polygon","coordinates":[[[-81.827587,32.651572],[-81.548263,32.487264],[-81.433247,32.240802],[-81.783771,32.153171],[-81.969987,32.268186],[-82.030233,32.536556],[-82.002849,32.607757],[-81.838541,32.651572],[-81.827587,32.651572]]]}}, -{"type":"Feature","id":"13033","properties":{"name":"Burke"},"geometry":{"type":"Polygon","coordinates":[[[-82.189065,33.292374],[-81.849494,33.248559],[-81.756386,33.199266],[-81.613986,33.095204],[-81.542786,33.045912],[-81.76734,32.908988],[-81.860448,32.952804],[-82.145249,32.810403],[-82.315034,32.837788],[-82.265742,33.264989],[-82.189065,33.292374]]]}}, -{"type":"Feature","id":"13035","properties":{"name":"Butts"},"geometry":{"type":"Polygon","coordinates":[[[-83.925255,33.451205],[-83.865008,33.369051],[-83.821193,33.182835],[-84.001932,33.204743],[-84.040271,33.204743],[-84.122425,33.204743],[-84.100517,33.297851],[-83.925255,33.451205]]]}}, -{"type":"Feature","id":"13037","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-84.544149,31.621907],[-84.451041,31.621907],[-84.429133,31.435691],[-84.637257,31.435691],[-84.817996,31.501415],[-84.817996,31.621907],[-84.544149,31.621907]]]}}, -{"type":"Feature","id":"13039","properties":{"name":"Camden"},"geometry":{"type":"Polygon","coordinates":[[[-81.76734,31.167321],[-81.444201,31.013967],[-81.444201,30.707258],[-81.904264,30.816797],[-81.937125,31.046829],[-81.76734,31.167321]]]}}, -{"type":"Feature","id":"13043","properties":{"name":"Candler"},"geometry":{"type":"Polygon","coordinates":[[[-82.030233,32.536556],[-81.969987,32.268186],[-82.024756,32.27914],[-82.23288,32.317479],[-82.030233,32.536556]]]}}, -{"type":"Feature","id":"13045","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-85.037074,33.812683],[-84.90015,33.779822],[-84.807042,33.571698],[-84.850858,33.511452],[-85.015166,33.423821],[-85.29449,33.429298],[-85.305444,33.484067],[-85.338305,33.653852],[-85.037074,33.812683]]]}}, -{"type":"Feature","id":"13047","properties":{"name":"Catoosa"},"geometry":{"type":"Polygon","coordinates":[[[-85.267105,34.984749],[-84.982304,34.990226],[-85.146612,34.765671],[-85.267105,34.984749]]]}}, -{"type":"Feature","id":"13049","properties":{"name":"Charlton"},"geometry":{"type":"Polygon","coordinates":[[[-81.986418,31.057782],[-81.937125,31.046829],[-81.904264,30.816797],[-82.052141,30.362211],[-82.216449,30.570335],[-82.134295,31.00849],[-81.986418,31.057782]]]}}, -{"type":"Feature","id":"13051","properties":{"name":"Chatham"},"geometry":{"type":"Polygon","coordinates":[[[-81.1594,32.229848],[-81.148446,32.224371],[-80.885553,32.032678],[-81.153923,31.725969],[-81.389431,32.098401],[-81.1594,32.229848]]]}}, -{"type":"Feature","id":"13053","properties":{"name":"Chattahoochee"},"geometry":{"type":"Polygon","coordinates":[[[-84.637257,32.536556],[-84.659165,32.235325],[-84.922058,32.229848],[-84.982304,32.372248],[-84.692026,32.520126],[-84.637257,32.536556]]]}}, -{"type":"Feature","id":"13055","properties":{"name":"Chattooga"},"geometry":{"type":"Polygon","coordinates":[[[-85.108274,34.584932],[-85.464275,34.2837],[-85.513567,34.524686],[-85.529998,34.590409],[-85.108274,34.584932]]]}}, -{"type":"Feature","id":"13057","properties":{"name":"Cherokee"},"geometry":{"type":"Polygon","coordinates":[[[-84.582488,34.387762],[-84.259348,34.382285],[-84.259348,34.332993],[-84.259348,34.185115],[-84.407226,34.108438],[-84.418179,34.075577],[-84.615349,34.081054],[-84.659165,34.075577],[-84.653688,34.415147],[-84.582488,34.387762]]]}}, -{"type":"Feature","id":"13059","properties":{"name":"Clarke"},"geometry":{"type":"Polygon","coordinates":[[[-83.36113,34.042715],[-83.257068,33.998899],[-83.273499,33.845545],[-83.530915,33.960561],[-83.536392,33.966038],[-83.36113,34.042715]]]}}, -{"type":"Feature","id":"13061","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-85.124705,31.780739],[-84.960397,31.775262],[-84.817996,31.621907],[-84.817996,31.501415],[-85.048028,31.517845],[-85.124705,31.764308],[-85.141136,31.780739],[-85.124705,31.780739]]]}}, -{"type":"Feature","id":"13063","properties":{"name":"Clayton"},"geometry":{"type":"Polygon","coordinates":[[[-84.352456,33.648375],[-84.281256,33.648375],[-84.352456,33.35262],[-84.368887,33.35262],[-84.385318,33.35262],[-84.451041,33.54979],[-84.456518,33.54979],[-84.352456,33.648375]]]}}, -{"type":"Feature","id":"13065","properties":{"name":"Clinch"},"geometry":{"type":"Polygon","coordinates":[[[-82.972267,31.183752],[-82.671035,31.183752],[-82.419096,30.581289],[-82.457435,30.586766],[-82.583404,30.592243],[-82.972267,30.871567],[-82.972267,31.183752]]]}}, -{"type":"Feature","id":"13067","properties":{"name":"Cobb"},"geometry":{"type":"Polygon","coordinates":[[[-84.615349,34.081054],[-84.418179,34.075577],[-84.577011,33.741483],[-84.724888,33.807207],[-84.735842,34.081054],[-84.659165,34.075577],[-84.615349,34.081054]]]}}, -{"type":"Feature","id":"13069","properties":{"name":"Coffee"},"geometry":{"type":"Polygon","coordinates":[[[-82.994175,31.780739],[-82.835344,31.8136],[-82.62722,31.6712],[-82.599835,31.468553],[-82.62722,31.364491],[-83.142052,31.419261],[-83.147529,31.47403],[-82.999652,31.6712],[-82.994175,31.780739]]]}}, -{"type":"Feature","id":"13071","properties":{"name":"Colquitt"},"geometry":{"type":"Polygon","coordinates":[[[-83.974547,31.337106],[-83.651408,31.331629],[-83.514484,31.326153],[-83.574731,31.07969],[-83.739039,31.035875],[-84.001932,31.07969],[-84.001932,31.337106],[-83.974547,31.337106]]]}}, -{"type":"Feature","id":"13073","properties":{"name":"Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-82.216449,33.686714],[-82.117864,33.599083],[-82.030233,33.544313],[-82.293127,33.35262],[-82.424573,33.648375],[-82.216449,33.686714]]]}}, -{"type":"Feature","id":"13075","properties":{"name":"Cook"},"geometry":{"type":"Polygon","coordinates":[[[-83.43233,31.34806],[-83.295407,31.024921],[-83.383038,31.030398],[-83.476146,31.030398],[-83.498053,31.052306],[-83.574731,31.07969],[-83.514484,31.326153],[-83.43233,31.34806]]]}}, -{"type":"Feature","id":"13077","properties":{"name":"Coweta"},"geometry":{"type":"Polygon","coordinates":[[[-84.681073,33.511452],[-84.609872,33.500498],[-84.494857,33.259513],[-84.500334,33.221174],[-84.861812,33.193789],[-84.938489,33.226651],[-85.015166,33.423821],[-84.850858,33.511452],[-84.681073,33.511452]]]}}, -{"type":"Feature","id":"13079","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-84.122425,32.848742],[-83.892393,32.848742],[-83.7007,32.689911],[-83.7007,32.689911],[-83.766424,32.695388],[-84.001932,32.531079],[-84.204579,32.689911],[-84.122425,32.848742]]]}}, -{"type":"Feature","id":"13081","properties":{"name":"Crisp"},"geometry":{"type":"Polygon","coordinates":[[[-83.963593,32.032678],[-83.607592,32.027201],[-83.613069,31.851939],[-83.804762,31.802646],[-83.941686,31.846462],[-83.925255,31.912185],[-83.963593,32.032678]]]}}, -{"type":"Feature","id":"13083","properties":{"name":"Dade"},"geometry":{"type":"Polygon","coordinates":[[[-85.475229,34.984749],[-85.36569,34.984749],[-85.535475,34.623271],[-85.584768,34.858779],[-85.606675,34.984749],[-85.475229,34.984749]]]}}, -{"type":"Feature","id":"13085","properties":{"name":"Dawson"},"geometry":{"type":"Polygon","coordinates":[[[-84.199102,34.617794],[-84.188148,34.601363],[-83.980024,34.420624],[-83.958116,34.332993],[-84.259348,34.332993],[-84.259348,34.382285],[-84.346979,34.563024],[-84.199102,34.617794]]]}}, -{"type":"Feature","id":"13087","properties":{"name":"Decatur"},"geometry":{"type":"Polygon","coordinates":[[[-84.544149,31.07969],[-84.544149,31.07969],[-84.50581,31.07969],[-84.374364,31.07969],[-84.379841,30.690827],[-84.861812,30.712735],[-84.730365,31.068736],[-84.544149,31.07969]]]}}, -{"type":"Feature","id":"13089","properties":{"name":"DeKalb"},"geometry":{"type":"Polygon","coordinates":[[[-84.275779,33.955084],[-84.02384,33.752437],[-84.182671,33.648375],[-84.226487,33.637421],[-84.281256,33.648375],[-84.352456,33.648375],[-84.275779,33.955084],[-84.275779,33.955084]]]}}, -{"type":"Feature","id":"13091","properties":{"name":"Dodge"},"geometry":{"type":"Polygon","coordinates":[[[-83.136575,32.421541],[-82.884636,32.196986],[-82.928452,32.13674],[-82.950359,32.120309],[-83.207776,31.901231],[-83.339222,32.103878],[-83.344699,32.273663],[-83.136575,32.421541]]]}}, -{"type":"Feature","id":"13093","properties":{"name":"Dooly"},"geometry":{"type":"Polygon","coordinates":[[[-83.848578,32.290094],[-83.613069,32.290094],[-83.607592,32.120309],[-83.607592,32.027201],[-83.963593,32.032678],[-84.029317,32.169601],[-83.848578,32.290094]]]}}, -{"type":"Feature","id":"13095","properties":{"name":"Dougherty"},"geometry":{"type":"Polygon","coordinates":[[[-84.018363,31.649292],[-83.996455,31.441168],[-84.062178,31.441168],[-84.138855,31.441168],[-84.429133,31.435691],[-84.451041,31.621907],[-84.297687,31.621907],[-84.018363,31.649292]]]}}, -{"type":"Feature","id":"13097","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-84.724888,33.807207],[-84.577011,33.741483],[-84.807042,33.571698],[-84.90015,33.779822],[-84.724888,33.807207]]]}}, -{"type":"Feature","id":"13099","properties":{"name":"Early"},"geometry":{"type":"Polygon","coordinates":[[[-85.086366,31.309722],[-85.048028,31.517845],[-84.817996,31.501415],[-84.637257,31.435691],[-84.642734,31.260429],[-84.922058,31.074213],[-85.02612,31.074213],[-85.086366,31.309722]]]}}, -{"type":"Feature","id":"13101","properties":{"name":"Echols"},"geometry":{"type":"Polygon","coordinates":[[[-82.972267,30.871567],[-82.583404,30.592243],[-82.687466,30.597719],[-83.136575,30.625104],[-83.02156,30.849659],[-82.972267,30.871567]]]}}, -{"type":"Feature","id":"13103","properties":{"name":"Effingham"},"geometry":{"type":"Polygon","coordinates":[[[-81.389431,32.596803],[-81.279893,32.558464],[-81.148446,32.224371],[-81.1594,32.229848],[-81.389431,32.098401],[-81.42777,32.235325],[-81.433247,32.240802],[-81.548263,32.487264],[-81.389431,32.596803]]]}}, -{"type":"Feature","id":"13105","properties":{"name":"Elbert"},"geometry":{"type":"Polygon","coordinates":[[[-82.775097,34.289177],[-82.742236,34.207023],[-82.594358,34.01533],[-82.566974,33.955084],[-82.643651,33.982469],[-82.731282,33.982469],[-82.780574,33.971515],[-82.977744,34.042715],[-83.076329,34.228931],[-82.775097,34.289177]]]}}, -{"type":"Feature","id":"13107","properties":{"name":"Emanuel"},"geometry":{"type":"Polygon","coordinates":[[[-82.315034,32.837788],[-82.145249,32.810403],[-82.002849,32.607757],[-82.030233,32.536556],[-82.23288,32.317479],[-82.408142,32.355817],[-82.550543,32.498218],[-82.649128,32.514649],[-82.435527,32.761111],[-82.315034,32.837788]]]}}, -{"type":"Feature","id":"13109","properties":{"name":"Evans"},"geometry":{"type":"Polygon","coordinates":[[[-82.024756,32.27914],[-81.969987,32.268186],[-81.783771,32.153171],[-81.718048,32.087447],[-81.761863,32.049109],[-82.024756,32.27914]]]}}, -{"type":"Feature","id":"13111","properties":{"name":"Fannin"},"geometry":{"type":"Polygon","coordinates":[[[-84.319594,34.990226],[-84.127902,34.990226],[-84.155286,34.650655],[-84.188148,34.601363],[-84.199102,34.617794],[-84.620826,34.853302],[-84.620826,34.990226],[-84.319594,34.990226]]]}}, -{"type":"Feature","id":"13113","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-84.451041,33.54979],[-84.385318,33.35262],[-84.494857,33.259513],[-84.609872,33.500498],[-84.456518,33.54979],[-84.451041,33.54979]]]}}, -{"type":"Feature","id":"13115","properties":{"name":"Floyd"},"geometry":{"type":"Polygon","coordinates":[[[-85.09732,34.584932],[-85.069935,34.584932],[-85.004212,34.393239],[-85.048028,34.097484],[-85.42046,34.081054],[-85.464275,34.2837],[-85.108274,34.584932],[-85.09732,34.584932]]]}}, -{"type":"Feature","id":"13117","properties":{"name":"Forsyth"},"geometry":{"type":"Polygon","coordinates":[[[-84.259348,34.332993],[-83.958116,34.332993],[-84.062178,34.168685],[-84.09504,34.048192],[-84.259348,34.185115],[-84.259348,34.332993]]]}}, -{"type":"Feature","id":"13119","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-83.125621,34.519209],[-83.103714,34.53564],[-83.048944,34.497301],[-83.114668,34.272746],[-83.120145,34.272746],[-83.355653,34.223454],[-83.399469,34.458962],[-83.125621,34.519209]]]}}, -{"type":"Feature","id":"13121","properties":{"name":"Fulton"},"geometry":{"type":"Polygon","coordinates":[[[-84.407226,34.108438],[-84.259348,34.185115],[-84.09504,34.048192],[-84.275779,33.955084],[-84.352456,33.648375],[-84.456518,33.54979],[-84.609872,33.500498],[-84.681073,33.511452],[-84.850858,33.511452],[-84.807042,33.571698],[-84.577011,33.741483],[-84.418179,34.075577],[-84.407226,34.108438]]]}}, -{"type":"Feature","id":"13123","properties":{"name":"Gilmer"},"geometry":{"type":"Polygon","coordinates":[[[-84.620826,34.853302],[-84.199102,34.617794],[-84.346979,34.563024],[-84.653688,34.546593],[-84.653688,34.584932],[-84.620826,34.853302]]]}}, -{"type":"Feature","id":"13125","properties":{"name":"Glascock"},"geometry":{"type":"Polygon","coordinates":[[[-82.687466,33.270466],[-82.43005,33.275943],[-82.660082,33.128066],[-82.747713,33.237605],[-82.75319,33.254036],[-82.687466,33.270466]]]}}, -{"type":"Feature","id":"13127","properties":{"name":"Glynn"},"geometry":{"type":"Polygon","coordinates":[[[-81.279893,31.293291],[-81.268939,31.293291],[-81.444201,31.013967],[-81.76734,31.167321],[-81.729002,31.331629],[-81.62494,31.452122],[-81.279893,31.293291]]]}}, -{"type":"Feature","id":"13129","properties":{"name":"Gordon"},"geometry":{"type":"Polygon","coordinates":[[[-84.916581,34.634225],[-84.653688,34.584932],[-84.653688,34.546593],[-84.653688,34.415147],[-84.933012,34.398716],[-85.004212,34.393239],[-85.069935,34.584932],[-85.048028,34.623271],[-84.916581,34.634225]]]}}, -{"type":"Feature","id":"13131","properties":{"name":"Grady"},"geometry":{"type":"Polygon","coordinates":[[[-84.270302,31.07969],[-84.116948,31.07969],[-84.084086,30.674397],[-84.281256,30.685351],[-84.379841,30.690827],[-84.374364,31.07969],[-84.270302,31.07969]]]}}, -{"type":"Feature","id":"13133","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-83.28993,33.736006],[-83.278976,33.763391],[-82.994175,33.692191],[-83.010606,33.467636],[-83.16396,33.35262],[-83.278976,33.484067],[-83.404945,33.697668],[-83.28993,33.736006]]]}}, -{"type":"Feature","id":"13135","properties":{"name":"Gwinnett"},"geometry":{"type":"Polygon","coordinates":[[[-83.990978,34.1413],[-83.815716,34.124869],[-83.799285,33.927699],[-83.980024,33.785299],[-84.02384,33.752437],[-84.275779,33.955084],[-84.275779,33.955084],[-84.09504,34.048192],[-84.062178,34.168685],[-83.990978,34.1413]]]}}, -{"type":"Feature","id":"13137","properties":{"name":"Habersham"},"geometry":{"type":"Polygon","coordinates":[[[-83.651408,34.820441],[-83.350176,34.716379],[-83.339222,34.688994],[-83.459715,34.48087],[-83.552823,34.486347],[-83.613069,34.431578],[-83.667839,34.502778],[-83.684269,34.798533],[-83.651408,34.820441]]]}}, -{"type":"Feature","id":"13139","properties":{"name":"Hall"},"geometry":{"type":"Polygon","coordinates":[[[-83.788331,34.513732],[-83.667839,34.502778],[-83.613069,34.431578],[-83.618546,34.294654],[-83.815716,34.124869],[-83.990978,34.1413],[-84.062178,34.168685],[-83.958116,34.332993],[-83.980024,34.420624],[-83.843101,34.502778],[-83.788331,34.513732]]]}}, -{"type":"Feature","id":"13141","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-83.010606,33.467636],[-82.851774,33.445728],[-82.75319,33.254036],[-82.747713,33.237605],[-83.054421,33.078773],[-83.273499,33.188312],[-83.16396,33.35262],[-83.010606,33.467636],[-83.010606,33.467636]]]}}, -{"type":"Feature","id":"13143","properties":{"name":"Haralson"},"geometry":{"type":"Polygon","coordinates":[[[-85.310921,33.900315],[-85.048028,33.905791],[-85.037074,33.812683],[-85.338305,33.653852],[-85.387598,33.900315],[-85.310921,33.900315]]]}}, -{"type":"Feature","id":"13145","properties":{"name":"Harris"},"geometry":{"type":"Polygon","coordinates":[[[-84.861812,32.87065],[-84.70298,32.843265],[-84.692026,32.585849],[-85.02612,32.607757],[-85.080889,32.607757],[-85.130182,32.74468],[-85.184951,32.87065],[-84.861812,32.87065],[-84.861812,32.87065]]]}}, -{"type":"Feature","id":"13147","properties":{"name":"Hart"},"geometry":{"type":"Polygon","coordinates":[[[-83.048944,34.497301],[-82.994175,34.48087],[-82.775097,34.289177],[-83.076329,34.228931],[-83.114668,34.272746],[-83.048944,34.497301]]]}}, -{"type":"Feature","id":"13149","properties":{"name":"Heard"},"geometry":{"type":"Polygon","coordinates":[[[-85.015166,33.423821],[-84.938489,33.226651],[-84.938489,33.226651],[-85.234244,33.128066],[-85.29449,33.429298],[-85.015166,33.423821]]]}}, -{"type":"Feature","id":"13151","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-84.226487,33.637421],[-84.182671,33.648375],[-84.045747,33.527883],[-83.925255,33.451205],[-84.100517,33.297851],[-84.352456,33.35262],[-84.281256,33.648375],[-84.226487,33.637421]]]}}, -{"type":"Feature","id":"13153","properties":{"name":"Houston"},"geometry":{"type":"Polygon","coordinates":[[[-83.7007,32.689911],[-83.7007,32.689911],[-83.596638,32.662526],[-83.498053,32.454402],[-83.498053,32.399633],[-83.613069,32.290094],[-83.848578,32.290094],[-83.848578,32.465356],[-83.7007,32.689911]]]}}, -{"type":"Feature","id":"13155","properties":{"name":"Irwin"},"geometry":{"type":"Polygon","coordinates":[[[-83.454238,31.758831],[-82.999652,31.6712],[-83.147529,31.47403],[-83.240637,31.47403],[-83.339222,31.47403],[-83.498053,31.594523],[-83.454238,31.758831]]]}}, -{"type":"Feature","id":"13157","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-83.618546,34.289177],[-83.404945,34.196069],[-83.36113,34.042715],[-83.536392,33.966038],[-83.815716,34.124869],[-83.618546,34.294654],[-83.618546,34.289177]]]}}, -{"type":"Feature","id":"13159","properties":{"name":"Jasper"},"geometry":{"type":"Polygon","coordinates":[[[-83.684269,33.527883],[-83.536392,33.434775],[-83.547346,33.171881],[-83.815716,33.133543],[-83.821193,33.182835],[-83.865008,33.369051],[-83.684269,33.527883]]]}}, -{"type":"Feature","id":"13161","properties":{"name":"Jeff Davis"},"geometry":{"type":"Polygon","coordinates":[[[-82.468389,31.966955],[-82.43005,31.966955],[-82.523158,31.709538],[-82.62722,31.6712],[-82.835344,31.8136],[-82.643651,31.917662],[-82.545066,31.961478],[-82.479343,31.972432],[-82.468389,31.966955]]]}}, -{"type":"Feature","id":"13163","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-82.386235,33.314282],[-82.353373,33.314282],[-82.265742,33.264989],[-82.315034,32.837788],[-82.435527,32.761111],[-82.523158,32.821357],[-82.660082,33.128066],[-82.43005,33.275943],[-82.386235,33.314282]]]}}, -{"type":"Feature","id":"13165","properties":{"name":"Jenkins"},"geometry":{"type":"Polygon","coordinates":[[[-81.860448,32.952804],[-81.76734,32.908988],[-81.838541,32.651572],[-82.002849,32.607757],[-82.145249,32.810403],[-81.860448,32.952804]]]}}, -{"type":"Feature","id":"13167","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-82.523158,32.821357],[-82.435527,32.761111],[-82.649128,32.514649],[-82.955836,32.706342],[-82.944882,32.761111],[-82.523158,32.821357]]]}}, -{"type":"Feature","id":"13169","properties":{"name":"Jones"},"geometry":{"type":"Polygon","coordinates":[[[-83.426853,33.182835],[-83.355653,32.925419],[-83.404945,32.898034],[-83.514484,32.843265],[-83.711654,32.952804],[-83.815716,33.133543],[-83.547346,33.171881],[-83.426853,33.182835]]]}}, -{"type":"Feature","id":"13171","properties":{"name":"Lamar"},"geometry":{"type":"Polygon","coordinates":[[[-84.040271,33.204743],[-84.122425,32.930896],[-84.270302,32.991142],[-84.248394,33.188312],[-84.122425,33.204743],[-84.040271,33.204743]]]}}, -{"type":"Feature","id":"13173","properties":{"name":"Lanier"},"geometry":{"type":"Polygon","coordinates":[[[-83.032514,31.183752],[-82.972267,31.183752],[-82.972267,30.871567],[-83.02156,30.849659],[-83.196822,31.024921],[-83.048944,31.183752],[-83.032514,31.183752]]]}}, -{"type":"Feature","id":"13175","properties":{"name":"Laurens"},"geometry":{"type":"Polygon","coordinates":[[[-83.224206,32.585849],[-82.955836,32.706342],[-82.649128,32.514649],[-82.720328,32.312002],[-82.884636,32.196986],[-83.136575,32.421541],[-83.224206,32.585849]]]}}, -{"type":"Feature","id":"13177","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-84.259348,31.917662],[-83.925255,31.912185],[-83.941686,31.846462],[-84.018363,31.649292],[-84.297687,31.621907],[-84.336025,31.873847],[-84.259348,31.917662]]]}}, -{"type":"Feature","id":"13179","properties":{"name":"Liberty"},"geometry":{"type":"Polygon","coordinates":[[[-81.707094,32.087447],[-81.197738,31.725969],[-81.192262,31.567138],[-81.493493,31.698584],[-81.811156,31.999816],[-81.82211,32.016247],[-81.761863,32.049109],[-81.718048,32.087447],[-81.707094,32.087447]]]}}, -{"type":"Feature","id":"13181","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-82.643651,33.982469],[-82.566974,33.955084],[-82.216449,33.686714],[-82.424573,33.648375],[-82.479343,33.637421],[-82.643651,33.982469]]]}}, -{"type":"Feature","id":"13183","properties":{"name":"Long"},"geometry":{"type":"Polygon","coordinates":[[[-81.811156,31.999816],[-81.493493,31.698584],[-81.663278,31.539753],[-81.969987,31.791692],[-81.82211,32.016247],[-81.811156,31.999816]]]}}, -{"type":"Feature","id":"13185","properties":{"name":"Lowndes"},"geometry":{"type":"Polygon","coordinates":[[[-83.383038,31.030398],[-83.295407,31.024921],[-83.196822,31.024921],[-83.02156,30.849659],[-83.136575,30.625104],[-83.311837,30.636058],[-83.355653,30.636058],[-83.476146,31.030398],[-83.383038,31.030398]]]}}, -{"type":"Feature","id":"13187","properties":{"name":"Lumpkin"},"geometry":{"type":"Polygon","coordinates":[[[-83.854055,34.721856],[-83.843101,34.502778],[-83.980024,34.420624],[-84.188148,34.601363],[-84.155286,34.650655],[-83.854055,34.721856]]]}}, -{"type":"Feature","id":"13189","properties":{"name":"McDuffie"},"geometry":{"type":"Polygon","coordinates":[[[-82.424573,33.648375],[-82.293127,33.35262],[-82.353373,33.314282],[-82.386235,33.314282],[-82.649128,33.610037],[-82.479343,33.637421],[-82.424573,33.648375]]]}}, -{"type":"Feature","id":"13191","properties":{"name":"McIntosh"},"geometry":{"type":"Polygon","coordinates":[[[-81.493493,31.698584],[-81.192262,31.567138],[-81.268939,31.293291],[-81.279893,31.293291],[-81.62494,31.452122],[-81.663278,31.539753],[-81.493493,31.698584]]]}}, -{"type":"Feature","id":"13193","properties":{"name":"Macon"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-84.001932,32.531079],[-84.007409,32.520126],[-84.051224,32.520126],[-84.051224,32.520126],[-84.001932,32.531079]]],[[[-84.018363,32.503695],[-83.848578,32.465356],[-83.848578,32.290094],[-84.029317,32.169601],[-84.182671,32.229848],[-84.253871,32.372248],[-84.051224,32.520126],[-84.018363,32.503695]]]]}}, -{"type":"Feature","id":"13195","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-83.120145,34.272746],[-83.114668,34.272746],[-83.076329,34.228931],[-82.977744,34.042715],[-83.098237,34.026284],[-83.257068,33.998899],[-83.36113,34.042715],[-83.404945,34.196069],[-83.355653,34.223454],[-83.120145,34.272746]]]}}, -{"type":"Feature","id":"13197","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-84.637257,32.536556],[-84.445564,32.563941],[-84.390795,32.416064],[-84.429133,32.164124],[-84.429133,32.13674],[-84.648211,32.235325],[-84.659165,32.235325],[-84.637257,32.536556]]]}}, -{"type":"Feature","id":"13199","properties":{"name":"Meriwether"},"geometry":{"type":"Polygon","coordinates":[[[-84.861812,33.193789],[-84.500334,33.221174],[-84.494857,33.182835],[-84.527718,32.969235],[-84.50581,32.881604],[-84.70298,32.843265],[-84.861812,32.87065],[-84.861812,32.87065],[-84.861812,33.193789]]]}}, -{"type":"Feature","id":"13201","properties":{"name":"Miller"},"geometry":{"type":"Polygon","coordinates":[[[-84.642734,31.260429],[-84.544149,31.07969],[-84.544149,31.07969],[-84.730365,31.068736],[-84.922058,31.074213],[-84.642734,31.260429]]]}}, -{"type":"Feature","id":"13205","properties":{"name":"Mitchell"},"geometry":{"type":"Polygon","coordinates":[[[-84.062178,31.441168],[-83.996455,31.441168],[-84.001932,31.337106],[-84.001932,31.07969],[-84.100517,31.07969],[-84.116948,31.07969],[-84.270302,31.07969],[-84.374364,31.07969],[-84.50581,31.07969],[-84.138855,31.441168],[-84.062178,31.441168]]]}}, -{"type":"Feature","id":"13207","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-84.001932,33.204743],[-83.821193,33.182835],[-83.815716,33.133543],[-83.711654,32.952804],[-83.722608,32.952804],[-83.892393,32.848742],[-84.122425,32.848742],[-84.122425,32.930896],[-84.040271,33.204743],[-84.001932,33.204743]]]}}, -{"type":"Feature","id":"13209","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-82.408142,32.355817],[-82.479343,31.972432],[-82.545066,31.961478],[-82.654605,32.295571],[-82.408142,32.355817]]]}}, -{"type":"Feature","id":"13211","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-83.509007,33.812683],[-83.50353,33.81816],[-83.404945,33.697668],[-83.278976,33.484067],[-83.278976,33.484067],[-83.536392,33.434775],[-83.684269,33.527883],[-83.678792,33.599083],[-83.509007,33.812683]]]}}, -{"type":"Feature","id":"13213","properties":{"name":"Murray"},"geometry":{"type":"Polygon","coordinates":[[[-84.620826,34.990226],[-84.620826,34.853302],[-84.653688,34.584932],[-84.916581,34.634225],[-84.812519,34.990226],[-84.774181,34.990226],[-84.620826,34.990226]]]}}, -{"type":"Feature","id":"13215","properties":{"name":"Muscogee"},"geometry":{"type":"Polygon","coordinates":[[[-85.02612,32.607757],[-84.692026,32.585849],[-84.692026,32.520126],[-84.982304,32.372248],[-84.998735,32.509172],[-85.080889,32.607757],[-85.02612,32.607757]]]}}, -{"type":"Feature","id":"13217","properties":{"name":"Newton"},"geometry":{"type":"Polygon","coordinates":[[[-83.914301,33.74696],[-83.678792,33.599083],[-83.684269,33.527883],[-83.865008,33.369051],[-83.925255,33.451205],[-84.045747,33.527883],[-83.914301,33.74696]]]}}, -{"type":"Feature","id":"13219","properties":{"name":"Oconee"},"geometry":{"type":"Polygon","coordinates":[[[-83.530915,33.960561],[-83.273499,33.845545],[-83.278976,33.763391],[-83.28993,33.736006],[-83.404945,33.697668],[-83.50353,33.81816],[-83.645931,33.905791],[-83.536392,33.966038],[-83.530915,33.960561]]]}}, -{"type":"Feature","id":"13221","properties":{"name":"Oglethorpe"},"geometry":{"type":"Polygon","coordinates":[[[-83.098237,34.026284],[-82.977744,34.042715],[-82.780574,33.971515],[-82.950359,33.736006],[-82.994175,33.692191],[-83.278976,33.763391],[-83.273499,33.845545],[-83.257068,33.998899],[-83.098237,34.026284]]]}}, -{"type":"Feature","id":"13223","properties":{"name":"Paulding"},"geometry":{"type":"Polygon","coordinates":[[[-84.922058,34.081054],[-84.735842,34.081054],[-84.724888,33.807207],[-84.90015,33.779822],[-85.037074,33.812683],[-85.048028,33.905791],[-84.922058,34.081054]]]}}, -{"type":"Feature","id":"13225","properties":{"name":"Peach"},"geometry":{"type":"Polygon","coordinates":[[[-83.766424,32.695388],[-83.7007,32.689911],[-83.848578,32.465356],[-84.018363,32.503695],[-84.007409,32.520126],[-84.001932,32.531079],[-83.766424,32.695388]]]}}, -{"type":"Feature","id":"13227","properties":{"name":"Pickens"},"geometry":{"type":"Polygon","coordinates":[[[-84.346979,34.563024],[-84.259348,34.382285],[-84.582488,34.387762],[-84.653688,34.415147],[-84.653688,34.546593],[-84.346979,34.563024]]]}}, -{"type":"Feature","id":"13229","properties":{"name":"Pierce"},"geometry":{"type":"Polygon","coordinates":[[[-82.227403,31.528799],[-82.134295,31.468553],[-82.041187,31.375445],[-82.041187,31.369968],[-82.282173,31.227568],[-82.419096,31.419261],[-82.227403,31.528799]]]}}, -{"type":"Feature","id":"13231","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-84.494857,33.182835],[-84.248394,33.188312],[-84.270302,32.991142],[-84.36341,32.991142],[-84.527718,32.969235],[-84.494857,33.182835]]]}}, -{"type":"Feature","id":"13233","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-85.42046,34.081054],[-85.048028,34.097484],[-84.922058,34.081054],[-85.048028,33.905791],[-85.310921,33.900315],[-85.387598,33.900315],[-85.398552,33.966038],[-85.42046,34.081054]]]}}, -{"type":"Feature","id":"13235","properties":{"name":"Pulaski"},"geometry":{"type":"Polygon","coordinates":[[[-83.613069,32.290094],[-83.498053,32.399633],[-83.344699,32.273663],[-83.339222,32.103878],[-83.607592,32.120309],[-83.613069,32.290094]]]}}, -{"type":"Feature","id":"13237","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-83.278976,33.484067],[-83.278976,33.484067],[-83.16396,33.35262],[-83.273499,33.188312],[-83.426853,33.182835],[-83.547346,33.171881],[-83.536392,33.434775],[-83.278976,33.484067]]]}}, -{"type":"Feature","id":"13239","properties":{"name":"Quitman"},"geometry":{"type":"Polygon","coordinates":[[[-85.069935,31.994339],[-84.905627,31.923139],[-84.960397,31.775262],[-85.124705,31.780739],[-85.141136,31.780739],[-85.069935,31.994339]]]}}, -{"type":"Feature","id":"13241","properties":{"name":"Rabun"},"geometry":{"type":"Polygon","coordinates":[[[-83.109191,35.00118],[-83.350176,34.716379],[-83.651408,34.820441],[-83.547346,34.990226],[-83.481623,34.995703],[-83.109191,35.00118]]]}}, -{"type":"Feature","id":"13243","properties":{"name":"Randolph"},"geometry":{"type":"Polygon","coordinates":[[[-84.905627,31.923139],[-84.653688,31.917662],[-84.598918,31.917662],[-84.544149,31.621907],[-84.817996,31.621907],[-84.960397,31.775262],[-84.905627,31.923139]]]}}, -{"type":"Feature","id":"13245","properties":{"name":"Richmond"},"geometry":{"type":"Polygon","coordinates":[[[-82.030233,33.544313],[-82.013803,33.53336],[-81.849494,33.248559],[-82.189065,33.292374],[-82.265742,33.264989],[-82.353373,33.314282],[-82.293127,33.35262],[-82.030233,33.544313]]]}}, -{"type":"Feature","id":"13247","properties":{"name":"Rockdale"},"geometry":{"type":"Polygon","coordinates":[[[-83.980024,33.785299],[-83.914301,33.74696],[-84.045747,33.527883],[-84.182671,33.648375],[-84.02384,33.752437],[-83.980024,33.785299]]]}}, -{"type":"Feature","id":"13249","properties":{"name":"Schley"},"geometry":{"type":"Polygon","coordinates":[[[-84.36341,32.399633],[-84.253871,32.372248],[-84.182671,32.229848],[-84.429133,32.164124],[-84.390795,32.416064],[-84.36341,32.399633]]]}}, -{"type":"Feature","id":"13251","properties":{"name":"Screven"},"geometry":{"type":"Polygon","coordinates":[[[-81.542786,33.045912],[-81.411339,32.74468],[-81.389431,32.596803],[-81.548263,32.487264],[-81.827587,32.651572],[-81.838541,32.651572],[-81.76734,32.908988],[-81.542786,33.045912]]]}}, -{"type":"Feature","id":"13253","properties":{"name":"Seminole"},"geometry":{"type":"Polygon","coordinates":[[[-85.02612,31.074213],[-84.922058,31.074213],[-84.730365,31.068736],[-84.861812,30.712735],[-84.867289,30.712735],[-85.004212,31.003013],[-85.02612,31.074213]]]}}, -{"type":"Feature","id":"13255","properties":{"name":"Spalding"},"geometry":{"type":"Polygon","coordinates":[[[-84.368887,33.35262],[-84.352456,33.35262],[-84.100517,33.297851],[-84.122425,33.204743],[-84.248394,33.188312],[-84.494857,33.182835],[-84.500334,33.221174],[-84.494857,33.259513],[-84.385318,33.35262],[-84.368887,33.35262]]]}}, -{"type":"Feature","id":"13257","properties":{"name":"Stephens"},"geometry":{"type":"Polygon","coordinates":[[[-83.278976,34.645178],[-83.103714,34.53564],[-83.125621,34.519209],[-83.399469,34.458962],[-83.459715,34.48087],[-83.339222,34.688994],[-83.278976,34.645178]]]}}, -{"type":"Feature","id":"13259","properties":{"name":"Stewart"},"geometry":{"type":"Polygon","coordinates":[[[-84.659165,32.235325],[-84.648211,32.235325],[-84.653688,31.917662],[-84.905627,31.923139],[-85.069935,31.994339],[-85.053504,32.06554],[-84.922058,32.229848],[-84.659165,32.235325]]]}}, -{"type":"Feature","id":"13261","properties":{"name":"Sumter"},"geometry":{"type":"Polygon","coordinates":[[[-84.182671,32.229848],[-84.029317,32.169601],[-83.963593,32.032678],[-83.925255,31.912185],[-84.259348,31.917662],[-84.336025,31.873847],[-84.445564,31.966955],[-84.429133,32.13674],[-84.429133,32.164124],[-84.182671,32.229848]]]}}, -{"type":"Feature","id":"13263","properties":{"name":"Talbot"},"geometry":{"type":"Polygon","coordinates":[[[-84.50581,32.881604],[-84.286733,32.750157],[-84.445564,32.563941],[-84.637257,32.536556],[-84.692026,32.520126],[-84.692026,32.585849],[-84.70298,32.843265],[-84.50581,32.881604]]]}}, -{"type":"Feature","id":"13265","properties":{"name":"Taliaferro"},"geometry":{"type":"Polygon","coordinates":[[[-82.950359,33.736006],[-82.681989,33.599083],[-82.851774,33.445728],[-83.010606,33.467636],[-83.010606,33.467636],[-82.994175,33.692191],[-82.950359,33.736006]]]}}, -{"type":"Feature","id":"13267","properties":{"name":"Tattnall"},"geometry":{"type":"Polygon","coordinates":[[[-82.23288,32.317479],[-82.024756,32.27914],[-81.761863,32.049109],[-81.82211,32.016247],[-81.969987,31.791692],[-82.046664,31.824554],[-82.227403,31.912185],[-82.23288,32.317479]]]}}, -{"type":"Feature","id":"13269","properties":{"name":"Taylor"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-84.286733,32.750157],[-84.204579,32.689911],[-84.001932,32.531079],[-84.051224,32.520126],[-84.253871,32.372248],[-84.36341,32.399633],[-84.390795,32.416064],[-84.445564,32.563941],[-84.286733,32.750157]]],[[[-84.051224,32.520126],[-84.007409,32.520126],[-84.018363,32.503695],[-84.051224,32.520126],[-84.051224,32.520126]]]]}}, -{"type":"Feature","id":"13271","properties":{"name":"Telfair"},"geometry":{"type":"Polygon","coordinates":[[[-82.950359,32.120309],[-82.928452,32.13674],[-82.643651,31.917662],[-82.835344,31.8136],[-82.994175,31.780739],[-83.180391,31.846462],[-83.207776,31.901231],[-82.950359,32.120309]]]}}, -{"type":"Feature","id":"13273","properties":{"name":"Terrell"},"geometry":{"type":"Polygon","coordinates":[[[-84.297687,31.621907],[-84.451041,31.621907],[-84.544149,31.621907],[-84.598918,31.917662],[-84.445564,31.966955],[-84.336025,31.873847],[-84.297687,31.621907]]]}}, -{"type":"Feature","id":"13275","properties":{"name":"Thomas"},"geometry":{"type":"Polygon","coordinates":[[[-84.100517,31.07969],[-84.001932,31.07969],[-83.739039,31.035875],[-83.744516,30.657966],[-84.007409,30.674397],[-84.084086,30.674397],[-84.116948,31.07969],[-84.100517,31.07969]]]}}, -{"type":"Feature","id":"13277","properties":{"name":"Tift"},"geometry":{"type":"Polygon","coordinates":[[[-83.645931,31.594523],[-83.498053,31.594523],[-83.339222,31.47403],[-83.43233,31.34806],[-83.514484,31.326153],[-83.651408,31.331629],[-83.651408,31.567138],[-83.645931,31.594523]]]}}, -{"type":"Feature","id":"13279","properties":{"name":"Toombs"},"geometry":{"type":"Polygon","coordinates":[[[-82.408142,32.355817],[-82.23288,32.317479],[-82.227403,31.912185],[-82.43005,31.966955],[-82.468389,31.966955],[-82.479343,31.972432],[-82.408142,32.355817]]]}}, -{"type":"Feature","id":"13281","properties":{"name":"Towns"},"geometry":{"type":"Polygon","coordinates":[[[-83.936209,34.984749],[-83.547346,34.990226],[-83.651408,34.820441],[-83.684269,34.798533],[-83.782854,34.793056],[-83.936209,34.984749]]]}}, -{"type":"Feature","id":"13283","properties":{"name":"Treutlen"},"geometry":{"type":"Polygon","coordinates":[[[-82.550543,32.498218],[-82.408142,32.355817],[-82.654605,32.295571],[-82.720328,32.312002],[-82.649128,32.514649],[-82.550543,32.498218]]]}}, -{"type":"Feature","id":"13285","properties":{"name":"Troup"},"geometry":{"type":"Polygon","coordinates":[[[-84.938489,33.226651],[-84.938489,33.226651],[-84.861812,33.193789],[-84.861812,32.87065],[-85.184951,32.87065],[-85.234244,33.106158],[-85.234244,33.128066],[-84.938489,33.226651]]]}}, -{"type":"Feature","id":"13287","properties":{"name":"Turner"},"geometry":{"type":"Polygon","coordinates":[[[-83.613069,31.851939],[-83.481623,31.846462],[-83.454238,31.758831],[-83.498053,31.594523],[-83.645931,31.594523],[-83.651408,31.567138],[-83.804762,31.802646],[-83.613069,31.851939]]]}}, -{"type":"Feature","id":"13289","properties":{"name":"Twiggs"},"geometry":{"type":"Polygon","coordinates":[[[-83.393992,32.876127],[-83.224206,32.585849],[-83.498053,32.454402],[-83.596638,32.662526],[-83.514484,32.843265],[-83.404945,32.898034],[-83.393992,32.876127]]]}}, -{"type":"Feature","id":"13291","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-84.007409,34.984749],[-83.936209,34.984749],[-83.782854,34.793056],[-83.854055,34.721856],[-84.155286,34.650655],[-84.127902,34.990226],[-84.007409,34.984749]]]}}, -{"type":"Feature","id":"13293","properties":{"name":"Upson"},"geometry":{"type":"Polygon","coordinates":[[[-84.36341,32.991142],[-84.270302,32.991142],[-84.122425,32.930896],[-84.122425,32.848742],[-84.204579,32.689911],[-84.286733,32.750157],[-84.50581,32.881604],[-84.527718,32.969235],[-84.36341,32.991142]]]}}, -{"type":"Feature","id":"13295","properties":{"name":"Walker"},"geometry":{"type":"Polygon","coordinates":[[[-85.272582,34.984749],[-85.267105,34.984749],[-85.146612,34.765671],[-85.048028,34.623271],[-85.069935,34.584932],[-85.09732,34.584932],[-85.108274,34.584932],[-85.529998,34.590409],[-85.535475,34.623271],[-85.36569,34.984749],[-85.272582,34.984749]]]}}, -{"type":"Feature","id":"13297","properties":{"name":"Walton"},"geometry":{"type":"Polygon","coordinates":[[[-83.799285,33.927699],[-83.645931,33.905791],[-83.50353,33.81816],[-83.509007,33.812683],[-83.678792,33.599083],[-83.914301,33.74696],[-83.980024,33.785299],[-83.799285,33.927699]]]}}, -{"type":"Feature","id":"13299","properties":{"name":"Ware"},"geometry":{"type":"Polygon","coordinates":[[[-82.473866,31.419261],[-82.419096,31.419261],[-82.282173,31.227568],[-82.134295,31.00849],[-82.216449,30.570335],[-82.419096,30.581289],[-82.671035,31.183752],[-82.62722,31.364491],[-82.599835,31.468553],[-82.473866,31.419261]]]}}, -{"type":"Feature","id":"13301","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-82.649128,33.610037],[-82.386235,33.314282],[-82.43005,33.275943],[-82.687466,33.270466],[-82.75319,33.254036],[-82.851774,33.445728],[-82.681989,33.599083],[-82.649128,33.610037]]]}}, -{"type":"Feature","id":"13303","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-82.747713,33.237605],[-82.660082,33.128066],[-82.523158,32.821357],[-82.944882,32.761111],[-83.076329,32.947327],[-83.054421,33.078773],[-82.747713,33.237605]]]}}, -{"type":"Feature","id":"13305","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-82.134295,31.632861],[-82.046664,31.824554],[-81.969987,31.791692],[-81.663278,31.539753],[-81.62494,31.452122],[-81.729002,31.331629],[-82.041187,31.375445],[-82.134295,31.468553],[-82.134295,31.632861]]]}}, -{"type":"Feature","id":"13307","properties":{"name":"Webster"},"geometry":{"type":"Polygon","coordinates":[[[-84.648211,32.235325],[-84.429133,32.13674],[-84.445564,31.966955],[-84.598918,31.917662],[-84.653688,31.917662],[-84.648211,32.235325]]]}}, -{"type":"Feature","id":"13309","properties":{"name":"Wheeler"},"geometry":{"type":"Polygon","coordinates":[[[-82.720328,32.312002],[-82.654605,32.295571],[-82.545066,31.961478],[-82.643651,31.917662],[-82.928452,32.13674],[-82.884636,32.196986],[-82.720328,32.312002]]]}}, -{"type":"Feature","id":"13311","properties":{"name":"White"},"geometry":{"type":"Polygon","coordinates":[[[-83.782854,34.793056],[-83.684269,34.798533],[-83.667839,34.502778],[-83.788331,34.513732],[-83.843101,34.502778],[-83.854055,34.721856],[-83.782854,34.793056]]]}}, -{"type":"Feature","id":"13313","properties":{"name":"Whitfield"},"geometry":{"type":"Polygon","coordinates":[[[-84.976827,34.990226],[-84.812519,34.990226],[-84.916581,34.634225],[-85.048028,34.623271],[-85.146612,34.765671],[-84.982304,34.990226],[-84.976827,34.990226]]]}}, -{"type":"Feature","id":"13315","properties":{"name":"Wilcox"},"geometry":{"type":"Polygon","coordinates":[[[-83.607592,32.120309],[-83.339222,32.103878],[-83.207776,31.901231],[-83.180391,31.846462],[-83.481623,31.846462],[-83.613069,31.851939],[-83.607592,32.027201],[-83.607592,32.120309]]]}}, -{"type":"Feature","id":"13317","properties":{"name":"Wilkes"},"geometry":{"type":"Polygon","coordinates":[[[-82.731282,33.982469],[-82.643651,33.982469],[-82.479343,33.637421],[-82.649128,33.610037],[-82.681989,33.599083],[-82.950359,33.736006],[-82.780574,33.971515],[-82.731282,33.982469]]]}}, -{"type":"Feature","id":"13319","properties":{"name":"Wilkinson"},"geometry":{"type":"Polygon","coordinates":[[[-83.076329,32.947327],[-82.944882,32.761111],[-82.955836,32.706342],[-83.224206,32.585849],[-83.393992,32.876127],[-83.404945,32.898034],[-83.355653,32.925419],[-83.076329,32.947327]]]}}, -{"type":"Feature","id":"13321","properties":{"name":"Worth"},"geometry":{"type":"Polygon","coordinates":[[[-83.941686,31.846462],[-83.804762,31.802646],[-83.651408,31.567138],[-83.651408,31.331629],[-83.974547,31.337106],[-84.001932,31.337106],[-83.996455,31.441168],[-84.018363,31.649292],[-83.941686,31.846462]]]}}, -{"type":"Feature","id":"15001","properties":{"name":"Hawaii"},"geometry":{"type":"Polygon","coordinates":[[[-155.634835,18.948267],[-155.881297,19.035898],[-156.062036,19.73147],[-155.87582,20.26821],[-155.284311,20.021748],[-154.807817,19.523346],[-155.634835,18.948267]]]}}, -{"type":"Feature","id":"15003","properties":{"name":"Honolulu"},"geometry":{"type":"Polygon","coordinates":[[[-157.951581,21.697691],[-157.655826,21.303352],[-158.110412,21.303352],[-157.951581,21.697691]]]}}, -{"type":"Feature","id":"15009","properties":{"name":"Maui"},"geometry":{"type":"Polygon","coordinates":[[[-156.587823,21.029505],[-156.00179,20.793996],[-156.379699,20.580396],[-156.587823,21.029505]]]}}, -{"type":"Feature","id":"16001","properties":{"name":"Ada"},"geometry":{"type":"Polygon","coordinates":[[[-116.51305,43.8081],[-116.283018,43.8081],[-115.97631,43.589022],[-116.266588,43.112528],[-116.51305,43.28779],[-116.51305,43.8081]]]}}, -{"type":"Feature","id":"16003","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-116.688312,45.270443],[-116.146095,45.106135],[-116.157049,44.498194],[-116.299449,44.443425],[-116.901913,44.843241],[-116.78142,45.07875],[-116.688312,45.270443]]]}}, -{"type":"Feature","id":"16005","properties":{"name":"Bannock"},"geometry":{"type":"Polygon","coordinates":[[[-112.388914,43.01942],[-112.065774,43.024897],[-111.874081,42.416957],[-112.126021,42.28551],[-112.421776,42.504588],[-112.750392,42.953697],[-112.388914,43.01942]]]}}, -{"type":"Feature","id":"16007","properties":{"name":"Bear Lake"},"geometry":{"type":"Polygon","coordinates":[[[-111.468788,42.592219],[-111.047063,42.515542],[-111.047063,42.000709],[-111.507126,42.000709],[-111.600234,42.416957],[-111.468788,42.592219]]]}}, -{"type":"Feature","id":"16009","properties":{"name":"Benewah"},"geometry":{"type":"Polygon","coordinates":[[[-116.326834,47.411926],[-116.332311,47.023064],[-117.000498,47.132602],[-117.038836,47.127126],[-117.038836,47.258572],[-117.038836,47.368111],[-116.326834,47.411926]]]}}, -{"type":"Feature","id":"16011","properties":{"name":"Bingham"},"geometry":{"type":"Polygon","coordinates":[[[-112.695623,43.621884],[-112.52036,43.627361],[-112.52036,43.424714],[-111.589281,43.282313],[-111.589281,43.01942],[-112.065774,43.024897],[-112.388914,43.01942],[-112.750392,42.953697],[-113.007808,43.112528],[-113.007808,43.282313],[-112.695623,43.621884]]]}}, -{"type":"Feature","id":"16013","properties":{"name":"Blaine"},"geometry":{"type":"Polygon","coordinates":[[[-114.656367,43.917638],[-113.796488,43.567114],[-113.007808,43.282313],[-113.007808,43.112528],[-113.23784,42.625081],[-113.473348,42.668896],[-113.413102,43.200159],[-113.714333,43.200159],[-114.377043,43.200159],[-114.716614,43.813577],[-114.990461,43.857392],[-114.968553,43.939546],[-114.656367,43.917638]]]}}, -{"type":"Feature","id":"16015","properties":{"name":"Boise"},"geometry":{"type":"Polygon","coordinates":[[[-115.680555,44.235301],[-115.297169,44.339363],[-114.990461,43.9505],[-115.1712,44.087424],[-115.97631,43.589022],[-116.283018,43.8081],[-116.211818,44.153147],[-115.680555,44.235301]]]}}, -{"type":"Feature","id":"16017","properties":{"name":"Bonner"},"geometry":{"type":"Polygon","coordinates":[[[-116.836189,48.846885],[-116.786897,48.501838],[-116.04751,48.501838],[-116.04751,48.217037],[-116.04751,47.976051],[-116.310403,48.030821],[-116.321357,47.88842],[-116.567819,47.992482],[-117.044313,47.976051],[-117.044313,48.047251],[-117.033359,48.846885],[-116.836189,48.846885]]]}}, -{"type":"Feature","id":"16019","properties":{"name":"Bonneville"},"geometry":{"type":"Polygon","coordinates":[[[-111.775497,43.627361],[-111.627619,43.627361],[-111.397588,43.621884],[-111.047063,43.501391],[-111.047063,43.315175],[-111.041587,43.01942],[-111.589281,43.01942],[-111.589281,43.282313],[-112.52036,43.424714],[-112.52036,43.627361],[-111.775497,43.627361]]]}}, -{"type":"Feature","id":"16021","properties":{"name":"Boundary"},"geometry":{"type":"Polygon","coordinates":[[[-116.04751,49.000239],[-116.04751,48.501838],[-116.786897,48.501838],[-116.836189,48.846885],[-117.033359,48.846885],[-117.033359,49.000239],[-116.04751,49.000239]]]}}, -{"type":"Feature","id":"16023","properties":{"name":"Butte"},"geometry":{"type":"Polygon","coordinates":[[[-113.002331,44.235301],[-112.996854,44.235301],[-112.695623,43.972408],[-112.695623,43.621884],[-113.007808,43.282313],[-113.796488,43.567114],[-113.374763,43.8081],[-113.319994,44.235301],[-113.002331,44.235301]]]}}, -{"type":"Feature","id":"16025","properties":{"name":"Camas"},"geometry":{"type":"Polygon","coordinates":[[[-114.990461,43.857392],[-114.716614,43.813577],[-114.377043,43.200159],[-114.596121,43.200159],[-114.875445,43.200159],[-115.089045,43.200159],[-114.990461,43.857392]]]}}, -{"type":"Feature","id":"16027","properties":{"name":"Canyon"},"geometry":{"type":"Polygon","coordinates":[[[-116.97859,43.8793],[-116.71022,43.8081],[-116.51305,43.8081],[-116.51305,43.28779],[-116.989544,43.671176],[-117.027882,43.68213],[-116.97859,43.8793]]]}}, -{"type":"Feature","id":"16029","properties":{"name":"Caribou"},"geometry":{"type":"Polygon","coordinates":[[[-112.065774,43.024897],[-111.589281,43.01942],[-111.041587,43.01942],[-111.047063,42.515542],[-111.468788,42.592219],[-111.600234,42.416957],[-111.835743,42.416957],[-111.874081,42.416957],[-112.065774,43.024897]]]}}, -{"type":"Feature","id":"16031","properties":{"name":"Cassia"},"geometry":{"type":"Polygon","coordinates":[[[-113.473348,42.668896],[-113.23784,42.625081],[-113.002331,42.329326],[-113.002331,42.000709],[-114.04295,41.995232],[-114.283935,41.995232],[-113.999134,42.526496],[-113.933411,42.537449],[-113.473348,42.668896]]]}}, -{"type":"Feature","id":"16033","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-111.616665,44.547487],[-112.153405,44.060039],[-112.50393,44.060039],[-112.695623,43.972408],[-112.996854,44.235301],[-112.816115,44.377701],[-111.616665,44.547487]]]}}, -{"type":"Feature","id":"16035","properties":{"name":"Clearwater"},"geometry":{"type":"Polygon","coordinates":[[[-114.963076,46.935433],[-114.672798,46.738263],[-114.596121,46.634201],[-116.168003,46.371308],[-116.31588,46.426077],[-116.37065,46.464416],[-116.458281,46.628724],[-116.332311,46.935433],[-114.963076,46.935433]]]}}, -{"type":"Feature","id":"16037","properties":{"name":"Custer"},"geometry":{"type":"Polygon","coordinates":[[[-115.04523,44.750133],[-114.809722,44.81038],[-114.563259,44.574871],[-114.196304,44.859672],[-113.319994,44.235301],[-113.374763,43.8081],[-113.796488,43.567114],[-114.656367,43.917638],[-114.968553,43.939546],[-114.990461,43.9505],[-115.297169,44.339363],[-115.04523,44.750133]]]}}, -{"type":"Feature","id":"16039","properties":{"name":"Elmore"},"geometry":{"type":"Polygon","coordinates":[[[-114.990461,43.9505],[-114.968553,43.939546],[-114.990461,43.857392],[-115.089045,43.200159],[-115.039753,42.909881],[-115.039753,42.767481],[-116.266588,43.112528],[-115.97631,43.589022],[-115.1712,44.087424],[-114.990461,43.9505]]]}}, -{"type":"Feature","id":"16041","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-111.835743,42.416957],[-111.600234,42.416957],[-111.507126,42.000709],[-112.10959,41.995232],[-112.126021,42.28551],[-111.874081,42.416957],[-111.835743,42.416957]]]}}, -{"type":"Feature","id":"16043","properties":{"name":"Fremont"},"geometry":{"type":"Polygon","coordinates":[[[-111.37568,44.750133],[-111.047063,44.476286],[-111.047063,43.983362],[-111.397588,43.923115],[-111.978143,43.928592],[-112.153405,44.060039],[-111.616665,44.547487],[-111.479742,44.711795],[-111.37568,44.750133]]]}}, -{"type":"Feature","id":"16045","properties":{"name":"Gem"},"geometry":{"type":"Polygon","coordinates":[[[-116.157049,44.498194],[-116.211818,44.153147],[-116.283018,43.8081],[-116.51305,43.8081],[-116.71022,43.8081],[-116.452804,44.153147],[-116.299449,44.443425],[-116.157049,44.498194]]]}}, -{"type":"Feature","id":"16047","properties":{"name":"Gooding"},"geometry":{"type":"Polygon","coordinates":[[[-114.875445,43.200159],[-114.596121,43.200159],[-114.596121,42.849635],[-114.618029,42.646988],[-115.039753,42.909881],[-115.089045,43.200159],[-114.875445,43.200159]]]}}, -{"type":"Feature","id":"16049","properties":{"name":"Idaho"},"geometry":{"type":"Polygon","coordinates":[[[-114.333228,46.661586],[-114.557782,45.566198],[-114.694706,45.199243],[-115.828432,45.193766],[-116.146095,45.106135],[-116.688312,45.270443],[-116.463758,45.61549],[-116.792374,45.856475],[-116.699266,45.998876],[-116.168003,46.371308],[-114.596121,46.634201],[-114.333228,46.661586]]]}}, -{"type":"Feature","id":"16051","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-112.50393,44.060039],[-112.153405,44.060039],[-111.978143,43.928592],[-111.627619,43.627361],[-111.775497,43.627361],[-112.52036,43.627361],[-112.695623,43.621884],[-112.695623,43.972408],[-112.50393,44.060039]]]}}, -{"type":"Feature","id":"16053","properties":{"name":"Jerome"},"geometry":{"type":"Polygon","coordinates":[[[-114.596121,42.849635],[-113.933411,42.767481],[-113.933411,42.537449],[-113.999134,42.526496],[-114.618029,42.646988],[-114.596121,42.849635]]]}}, -{"type":"Feature","id":"16055","properties":{"name":"Kootenai"},"geometry":{"type":"Polygon","coordinates":[[[-116.567819,47.992482],[-116.321357,47.88842],[-116.326834,47.411926],[-117.038836,47.368111],[-117.044313,47.976051],[-116.567819,47.992482]]]}}, -{"type":"Feature","id":"16057","properties":{"name":"Latah"},"geometry":{"type":"Polygon","coordinates":[[[-117.000498,47.132602],[-116.332311,47.023064],[-116.332311,46.935433],[-116.458281,46.628724],[-116.644497,46.61777],[-117.038836,46.541093],[-117.038836,47.127126],[-117.000498,47.132602]]]}}, -{"type":"Feature","id":"16059","properties":{"name":"Lemhi"},"geometry":{"type":"Polygon","coordinates":[[[-113.944365,45.68669],[-113.456917,44.865149],[-112.816115,44.377701],[-112.996854,44.235301],[-113.002331,44.235301],[-113.319994,44.235301],[-114.196304,44.859672],[-114.563259,44.574871],[-114.809722,44.81038],[-114.694706,45.199243],[-114.557782,45.566198],[-113.944365,45.68669]]]}}, -{"type":"Feature","id":"16061","properties":{"name":"Lewis"},"geometry":{"type":"Polygon","coordinates":[[[-116.31588,46.426077],[-116.168003,46.371308],[-116.699266,45.998876],[-116.37065,46.464416],[-116.31588,46.426077]]]}}, -{"type":"Feature","id":"16063","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-114.377043,43.200159],[-113.714333,43.200159],[-113.933411,42.767481],[-114.596121,42.849635],[-114.596121,43.200159],[-114.377043,43.200159]]]}}, -{"type":"Feature","id":"16065","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-111.978143,43.928592],[-111.397588,43.923115],[-111.397588,43.621884],[-111.627619,43.627361],[-111.978143,43.928592]]]}}, -{"type":"Feature","id":"16067","properties":{"name":"Minidoka"},"geometry":{"type":"Polygon","coordinates":[[[-113.714333,43.200159],[-113.413102,43.200159],[-113.473348,42.668896],[-113.933411,42.537449],[-113.933411,42.767481],[-113.714333,43.200159]]]}}, -{"type":"Feature","id":"16069","properties":{"name":"Nez Perce"},"geometry":{"type":"Polygon","coordinates":[[[-116.644497,46.61777],[-116.458281,46.628724],[-116.37065,46.464416],[-116.699266,45.998876],[-116.792374,45.856475],[-116.918344,45.993399],[-117.038836,46.426077],[-117.038836,46.541093],[-116.644497,46.61777]]]}}, -{"type":"Feature","id":"16071","properties":{"name":"Oneida"},"geometry":{"type":"Polygon","coordinates":[[[-112.421776,42.504588],[-112.126021,42.28551],[-112.10959,41.995232],[-112.164359,41.995232],[-113.002331,42.000709],[-113.002331,42.329326],[-112.421776,42.504588]]]}}, -{"type":"Feature","id":"16073","properties":{"name":"Owyhee"},"geometry":{"type":"Polygon","coordinates":[[[-116.989544,43.671176],[-116.51305,43.28779],[-116.266588,43.112528],[-115.039753,42.767481],[-115.039753,41.995232],[-117.016928,42.000709],[-117.027882,42.000709],[-117.027882,43.68213],[-116.989544,43.671176]]]}}, -{"type":"Feature","id":"16075","properties":{"name":"Payette"},"geometry":{"type":"Polygon","coordinates":[[[-116.452804,44.153147],[-116.71022,43.8081],[-116.97859,43.8793],[-116.896436,44.153147],[-116.452804,44.153147]]]}}, -{"type":"Feature","id":"16077","properties":{"name":"Power"},"geometry":{"type":"Polygon","coordinates":[[[-112.421776,42.504588],[-113.002331,42.329326],[-113.23784,42.625081],[-113.007808,43.112528],[-112.750392,42.953697],[-112.421776,42.504588]]]}}, -{"type":"Feature","id":"16079","properties":{"name":"Shoshone"},"geometry":{"type":"Polygon","coordinates":[[[-116.310403,48.030821],[-116.04751,47.976051],[-115.658647,47.466696],[-114.963076,46.935433],[-116.332311,46.935433],[-116.332311,47.023064],[-116.326834,47.411926],[-116.321357,47.88842],[-116.310403,48.030821]]]}}, -{"type":"Feature","id":"16081","properties":{"name":"Teton"},"geometry":{"type":"Polygon","coordinates":[[[-111.047063,43.983362],[-111.047063,43.501391],[-111.397588,43.621884],[-111.397588,43.923115],[-111.047063,43.983362]]]}}, -{"type":"Feature","id":"16083","properties":{"name":"Twin Falls"},"geometry":{"type":"Polygon","coordinates":[[[-115.039753,42.909881],[-114.618029,42.646988],[-113.999134,42.526496],[-114.283935,41.995232],[-115.039753,41.995232],[-115.039753,42.767481],[-115.039753,42.909881]]]}}, -{"type":"Feature","id":"16085","properties":{"name":"Valley"},"geometry":{"type":"Polygon","coordinates":[[[-115.828432,45.193766],[-114.694706,45.199243],[-114.809722,44.81038],[-115.04523,44.750133],[-115.297169,44.339363],[-115.680555,44.235301],[-116.211818,44.153147],[-116.157049,44.498194],[-116.146095,45.106135],[-115.828432,45.193766]]]}}, -{"type":"Feature","id":"16087","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-116.901913,44.843241],[-116.299449,44.443425],[-116.452804,44.153147],[-116.896436,44.153147],[-117.219575,44.301024],[-116.901913,44.843241]]]}}, -{"type":"Feature","id":"17001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-91.204109,40.198796],[-90.913831,40.193319],[-90.913831,40.105688],[-90.919308,39.842795],[-91.36294,39.760641],[-91.43414,39.946857],[-91.50534,40.198796],[-91.204109,40.198796]]]}}, -{"type":"Feature","id":"17003","properties":{"name":"Alexander"},"geometry":{"type":"Polygon","coordinates":[[[-89.259795,37.334356],[-89.248841,37.334356],[-89.172164,37.065986],[-89.133825,36.983832],[-89.314564,37.011217],[-89.489826,37.252202],[-89.484349,37.334356],[-89.259795,37.334356]]]}}, -{"type":"Feature","id":"17005","properties":{"name":"Bond"},"geometry":{"type":"Polygon","coordinates":[[[-89.248841,39.026731],[-89.254318,38.74193],[-89.593888,38.74193],[-89.599365,38.74193],[-89.637704,38.999346],[-89.248841,39.026731]]]}}, -{"type":"Feature","id":"17007","properties":{"name":"Boone"},"geometry":{"type":"Polygon","coordinates":[[[-88.942132,42.493634],[-88.777824,42.493634],[-88.706624,42.493634],[-88.706624,42.154064],[-88.942132,42.154064],[-88.942132,42.493634]]]}}, -{"type":"Feature","id":"17009","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-90.913831,40.105688],[-90.514014,39.985195],[-90.585214,39.875656],[-90.57426,39.837318],[-90.919308,39.842795],[-90.913831,40.105688]]]}}, -{"type":"Feature","id":"17011","properties":{"name":"Bureau"},"geometry":{"type":"Polygon","coordinates":[[[-89.254318,41.584462],[-89.166687,41.584462],[-89.16121,41.310615],[-89.467918,41.146307],[-89.522688,41.146307],[-89.637704,41.146307],[-89.856781,41.233938],[-89.862258,41.584462],[-89.632227,41.584462],[-89.254318,41.584462]]]}}, -{"type":"Feature","id":"17013","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-90.935738,39.399163],[-90.612599,39.393686],[-90.601645,39.119839],[-90.448291,38.966484],[-90.667368,38.933623],[-90.722138,39.223901],[-90.935738,39.399163]]]}}, -{"type":"Feature","id":"17015","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-89.686996,42.197879],[-89.686996,41.929509],[-89.889643,41.929509],[-90.152536,41.929509],[-90.152536,42.033571],[-90.316844,42.192402],[-89.917028,42.197879],[-89.686996,42.197879]]]}}, -{"type":"Feature","id":"17017","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-90.355183,40.122119],[-89.993705,40.105688],[-89.993705,39.903041],[-89.993705,39.87018],[-90.585214,39.875656],[-90.514014,39.985195],[-90.355183,40.122119]]]}}, -{"type":"Feature","id":"17019","properties":{"name":"Champaign"},"geometry":{"type":"Polygon","coordinates":[[[-88.109637,40.401443],[-87.934375,40.401443],[-87.939852,39.881133],[-88.126068,39.881133],[-88.460161,39.881133],[-88.460161,40.28095],[-88.460161,40.401443],[-88.109637,40.401443]]]}}, -{"type":"Feature","id":"17021","properties":{"name":"Christian"},"geometry":{"type":"Polygon","coordinates":[[[-89.254318,39.820887],[-89.215979,39.81541],[-89.024286,39.656579],[-89.139302,39.34987],[-89.533642,39.525132],[-89.254318,39.820887]]]}}, -{"type":"Feature","id":"17023","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-87.76459,39.486794],[-87.529082,39.47584],[-87.605759,39.256762],[-87.644097,39.158177],[-87.786498,39.180085],[-87.950806,39.174608],[-88.005575,39.174608],[-88.011052,39.377255],[-87.96176,39.481317],[-87.76459,39.486794]]]}}, -{"type":"Feature","id":"17025","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-88.613516,38.917192],[-88.361576,38.911715],[-88.257515,38.845992],[-88.252038,38.599529],[-88.586131,38.605006],[-88.701147,38.605006],[-88.69567,38.824084],[-88.69567,38.917192],[-88.613516,38.917192]]]}}, -{"type":"Feature","id":"17027","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-89.593888,38.74193],[-89.254318,38.74193],[-89.139302,38.736453],[-89.144779,38.500944],[-89.320041,38.511898],[-89.703427,38.41879],[-89.708904,38.654299],[-89.599365,38.74193],[-89.593888,38.74193]]]}}, -{"type":"Feature","id":"17029","properties":{"name":"Coles"},"geometry":{"type":"Polygon","coordinates":[[[-88.065822,39.651102],[-87.967237,39.683964],[-87.96176,39.481317],[-88.011052,39.377255],[-88.142499,39.377255],[-88.471115,39.371778],[-88.471115,39.448455],[-88.471115,39.651102],[-88.065822,39.651102]]]}}, -{"type":"Feature","id":"17031","properties":{"name":"Cook"},"geometry":{"type":"Polygon","coordinates":[[[-88.120591,42.154064],[-87.759113,42.154064],[-87.523605,41.710431],[-87.523605,41.469446],[-88.027483,41.683047],[-87.928898,41.995232],[-88.262992,41.984279],[-88.235607,42.154064],[-88.197268,42.154064],[-88.120591,42.154064]]]}}, -{"type":"Feature","id":"17033","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-87.786498,39.180085],[-87.644097,39.158177],[-87.534558,38.900761],[-87.534558,38.851469],[-87.90699,38.851469],[-87.945329,38.851469],[-87.950806,39.174608],[-87.786498,39.180085]]]}}, -{"type":"Feature","id":"17035","properties":{"name":"Cumberland"},"geometry":{"type":"Polygon","coordinates":[[[-88.142499,39.377255],[-88.011052,39.377255],[-88.005575,39.174608],[-88.361576,39.169131],[-88.471115,39.212947],[-88.471115,39.371778],[-88.142499,39.377255]]]}}, -{"type":"Feature","id":"17037","properties":{"name":"DeKalb"},"geometry":{"type":"Polygon","coordinates":[[[-88.586131,42.154064],[-88.602562,41.721385],[-88.602562,41.633754],[-88.618993,41.633754],[-88.936655,41.628277],[-88.942132,41.891171],[-88.942132,42.154064],[-88.706624,42.154064],[-88.586131,42.154064]]]}}, -{"type":"Feature","id":"17039","properties":{"name":"De Witt"},"geometry":{"type":"Polygon","coordinates":[[[-88.920224,40.28095],[-88.575177,40.28095],[-88.744962,40.056395],[-88.805209,40.056395],[-89.144779,40.050919],[-89.150256,40.28095],[-88.920224,40.28095]]]}}, -{"type":"Feature","id":"17041","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-88.126068,39.881133],[-87.939852,39.881133],[-87.967237,39.683964],[-88.065822,39.651102],[-88.471115,39.651102],[-88.471115,39.793502],[-88.460161,39.881133],[-88.126068,39.881133]]]}}, -{"type":"Feature","id":"17043","properties":{"name":"DuPage"},"geometry":{"type":"Polygon","coordinates":[[[-87.928898,41.995232],[-88.027483,41.683047],[-88.03296,41.726862],[-88.262992,41.726862],[-88.262992,41.726862],[-88.262992,41.984279],[-87.928898,41.995232]]]}}, -{"type":"Feature","id":"17045","properties":{"name":"Edgar"},"geometry":{"type":"Polygon","coordinates":[[[-87.534558,39.881133],[-87.534558,39.607286],[-87.529082,39.47584],[-87.76459,39.486794],[-87.96176,39.481317],[-87.967237,39.683964],[-87.939852,39.881133],[-87.534558,39.881133]]]}}, -{"type":"Feature","id":"17047","properties":{"name":"Edwards"},"geometry":{"type":"Polygon","coordinates":[[[-88.005575,38.572145],[-87.956283,38.572145],[-87.989145,38.259959],[-88.005575,38.259959],[-88.153453,38.254482],[-88.147976,38.566668],[-88.005575,38.572145]]]}}, -{"type":"Feature","id":"17049","properties":{"name":"Effingham"},"geometry":{"type":"Polygon","coordinates":[[[-88.580654,39.212947],[-88.471115,39.212947],[-88.361576,39.169131],[-88.361576,38.911715],[-88.613516,38.917192],[-88.69567,38.917192],[-88.805209,39.218424],[-88.580654,39.212947]]]}}, -{"type":"Feature","id":"17051","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-89.139302,39.218424],[-88.805209,39.218424],[-88.69567,38.917192],[-88.69567,38.824084],[-88.777824,38.824084],[-89.139302,38.736453],[-89.254318,38.74193],[-89.248841,39.026731],[-89.139302,39.218424]]]}}, -{"type":"Feature","id":"17053","properties":{"name":"Ford"},"geometry":{"type":"Polygon","coordinates":[[[-88.131545,40.998429],[-87.934375,40.483597],[-87.934375,40.401443],[-88.109637,40.401443],[-88.460161,40.401443],[-88.460161,40.615043],[-88.246561,40.992952],[-88.131545,40.998429],[-88.131545,40.998429]]]}}, -{"type":"Feature","id":"17055","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-88.816163,38.128512],[-88.706624,38.123036],[-88.706624,37.909435],[-88.706624,37.865619],[-88.728531,37.865619],[-89.150256,37.860142],[-89.177641,37.947773],[-89.128348,38.123036],[-88.816163,38.128512]]]}}, -{"type":"Feature","id":"17057","properties":{"name":"Fulton"},"geometry":{"type":"Polygon","coordinates":[[[-90.442814,40.713628],[-89.988228,40.713628],[-89.873212,40.510982],[-89.922504,40.434304],[-90.201828,40.182365],[-90.448291,40.275473],[-90.442814,40.625997],[-90.442814,40.713628]]]}}, -{"type":"Feature","id":"17059","properties":{"name":"Gallatin"},"geometry":{"type":"Polygon","coordinates":[[[-88.137022,37.909435],[-88.054868,37.88205],[-88.027483,37.799896],[-88.131545,37.575342],[-88.378007,37.597249],[-88.37253,37.909435],[-88.37253,37.909435],[-88.137022,37.909435]]]}}, -{"type":"Feature","id":"17061","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-90.579737,39.519655],[-90.300413,39.519655],[-90.152536,39.519655],[-90.147059,39.262239],[-90.601645,39.119839],[-90.612599,39.393686],[-90.579737,39.519655]]]}}, -{"type":"Feature","id":"17063","properties":{"name":"Grundy"},"geometry":{"type":"Polygon","coordinates":[[[-88.279422,41.463969],[-88.252038,41.463969],[-88.246561,41.201076],[-88.252038,41.113445],[-88.410869,41.107968],[-88.586131,41.107968],[-88.597085,41.458492],[-88.279422,41.463969]]]}}, -{"type":"Feature","id":"17065","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-88.591608,38.254482],[-88.37253,38.254482],[-88.37253,37.909435],[-88.37253,37.909435],[-88.4273,37.909435],[-88.706624,37.909435],[-88.706624,38.123036],[-88.701147,38.254482],[-88.591608,38.254482]]]}}, -{"type":"Feature","id":"17067","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-91.187678,40.636951],[-90.902877,40.636951],[-90.908354,40.286427],[-90.913831,40.193319],[-91.204109,40.198796],[-91.50534,40.198796],[-91.499863,40.248088],[-91.417709,40.379535],[-91.187678,40.636951]]]}}, -{"type":"Feature","id":"17069","properties":{"name":"Hardin"},"geometry":{"type":"Polygon","coordinates":[[[-88.378007,37.597249],[-88.131545,37.575342],[-88.060345,37.504141],[-88.3561,37.405556],[-88.361576,37.405556],[-88.416346,37.421987],[-88.410869,37.597249],[-88.378007,37.597249]]]}}, -{"type":"Feature","id":"17071","properties":{"name":"Henderson"},"geometry":{"type":"Polygon","coordinates":[[[-90.946692,41.069629],[-90.787861,41.069629],[-90.787861,40.636951],[-90.8974,40.636951],[-90.902877,40.636951],[-91.187678,40.636951],[-91.111001,40.697198],[-90.946692,41.069629]]]}}, -{"type":"Feature","id":"17073","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-90.179921,41.584462],[-89.862258,41.584462],[-89.856781,41.233938],[-89.982751,41.151784],[-90.207305,41.151784],[-90.437337,41.151784],[-90.43186,41.327046],[-90.185398,41.584462],[-90.179921,41.584462]]]}}, -{"type":"Feature","id":"17075","properties":{"name":"Iroquois"},"geometry":{"type":"Polygon","coordinates":[[[-87.523605,41.009383],[-87.523605,40.735536],[-87.529082,40.489074],[-87.841267,40.489074],[-87.934375,40.483597],[-88.131545,40.998429],[-88.131545,40.998429],[-87.523605,41.009383]]]}}, -{"type":"Feature","id":"17077","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-89.566503,37.95325],[-89.177641,37.947773],[-89.150256,37.860142],[-89.155733,37.602726],[-89.522688,37.569865],[-89.676042,37.805373],[-89.593888,37.95325],[-89.566503,37.95325]]]}}, -{"type":"Feature","id":"17079","properties":{"name":"Jasper"},"geometry":{"type":"Polygon","coordinates":[[[-88.005575,39.174608],[-87.950806,39.174608],[-87.945329,38.851469],[-88.257515,38.845992],[-88.361576,38.911715],[-88.361576,39.169131],[-88.005575,39.174608]]]}}, -{"type":"Feature","id":"17081","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-88.914747,38.479037],[-88.701147,38.47356],[-88.701147,38.254482],[-88.706624,38.123036],[-88.816163,38.128512],[-89.128348,38.123036],[-89.144779,38.210667],[-89.144779,38.47356],[-88.914747,38.479037]]]}}, -{"type":"Feature","id":"17083","properties":{"name":"Jersey"},"geometry":{"type":"Polygon","coordinates":[[[-90.147059,39.262239],[-90.147059,38.999346],[-90.240167,38.999346],[-90.278506,38.922669],[-90.448291,38.966484],[-90.601645,39.119839],[-90.147059,39.262239]]]}}, -{"type":"Feature","id":"17085","properties":{"name":"Jo Daviess"},"geometry":{"type":"Polygon","coordinates":[[[-90.639984,42.510065],[-90.426383,42.504588],[-89.927981,42.504588],[-89.917028,42.197879],[-90.316844,42.192402],[-90.475675,42.384095],[-90.639984,42.510065]]]}}, -{"type":"Feature","id":"17087","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-88.876409,37.597249],[-88.706624,37.597249],[-88.712101,37.334356],[-88.931178,37.301494],[-89.046194,37.328879],[-89.040717,37.597249],[-88.876409,37.597249]]]}}, -{"type":"Feature","id":"17089","properties":{"name":"Kane"},"geometry":{"type":"Polygon","coordinates":[[[-88.454684,42.154064],[-88.235607,42.154064],[-88.262992,41.984279],[-88.262992,41.726862],[-88.602562,41.721385],[-88.586131,42.154064],[-88.454684,42.154064]]]}}, -{"type":"Feature","id":"17091","properties":{"name":"Kankakee"},"geometry":{"type":"Polygon","coordinates":[[[-87.786498,41.294184],[-87.529082,41.299661],[-87.529082,41.168214],[-87.523605,41.009383],[-88.131545,40.998429],[-88.246561,40.992952],[-88.252038,41.113445],[-88.246561,41.201076],[-87.786498,41.294184]]]}}, -{"type":"Feature","id":"17093","properties":{"name":"Kendall"},"geometry":{"type":"Polygon","coordinates":[[[-88.262992,41.726862],[-88.262992,41.726862],[-88.252038,41.463969],[-88.279422,41.463969],[-88.597085,41.458492],[-88.602562,41.633754],[-88.602562,41.721385],[-88.262992,41.726862]]]}}, -{"type":"Feature","id":"17095","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-90.207305,41.151784],[-89.982751,41.151784],[-89.988228,40.976521],[-89.988228,40.713628],[-90.442814,40.713628],[-90.437337,41.064153],[-90.437337,41.151784],[-90.207305,41.151784]]]}}, -{"type":"Feature","id":"17097","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-88.202745,42.493634],[-87.802929,42.493634],[-87.759113,42.154064],[-88.120591,42.154064],[-88.197268,42.154064],[-88.202745,42.493634]]]}}, -{"type":"Feature","id":"17099","properties":{"name":"La Salle"},"geometry":{"type":"Polygon","coordinates":[[[-88.618993,41.633754],[-88.602562,41.633754],[-88.597085,41.458492],[-88.586131,41.107968],[-88.931178,40.927229],[-89.046194,40.927229],[-89.16121,41.102491],[-89.16121,41.310615],[-89.166687,41.584462],[-88.936655,41.628277],[-88.618993,41.633754]]]}}, -{"type":"Feature","id":"17101","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-87.534558,38.851469],[-87.649574,38.566668],[-87.912467,38.572145],[-87.90699,38.851469],[-87.534558,38.851469]]]}}, -{"type":"Feature","id":"17103","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-89.544596,41.902124],[-88.942132,41.891171],[-88.936655,41.628277],[-89.166687,41.584462],[-89.254318,41.584462],[-89.632227,41.584462],[-89.632227,41.902124],[-89.544596,41.902124]]]}}, -{"type":"Feature","id":"17105","properties":{"name":"Livingston"},"geometry":{"type":"Polygon","coordinates":[[[-88.410869,41.107968],[-88.252038,41.113445],[-88.246561,40.992952],[-88.460161,40.615043],[-88.712101,40.757444],[-88.931178,40.751967],[-88.931178,40.927229],[-88.586131,41.107968],[-88.410869,41.107968]]]}}, -{"type":"Feature","id":"17107","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-89.265272,40.324766],[-89.150256,40.28095],[-89.144779,40.050919],[-89.215979,39.919472],[-89.489826,39.974241],[-89.577457,39.974241],[-89.599365,40.122119],[-89.604842,40.319289],[-89.265272,40.324766]]]}}, -{"type":"Feature","id":"17109","properties":{"name":"McDonough"},"geometry":{"type":"Polygon","coordinates":[[[-90.8974,40.636951],[-90.787861,40.636951],[-90.442814,40.625997],[-90.448291,40.275473],[-90.908354,40.286427],[-90.902877,40.636951],[-90.8974,40.636951]]]}}, -{"type":"Feature","id":"17111","properties":{"name":"McHenry"},"geometry":{"type":"Polygon","coordinates":[[[-88.219176,42.493634],[-88.202745,42.493634],[-88.197268,42.154064],[-88.235607,42.154064],[-88.454684,42.154064],[-88.586131,42.154064],[-88.706624,42.154064],[-88.706624,42.493634],[-88.306807,42.493634],[-88.219176,42.493634]]]}}, -{"type":"Feature","id":"17113","properties":{"name":"McLean"},"geometry":{"type":"Polygon","coordinates":[[[-88.712101,40.757444],[-88.460161,40.615043],[-88.460161,40.401443],[-88.460161,40.28095],[-88.575177,40.28095],[-88.920224,40.28095],[-89.150256,40.28095],[-89.265272,40.324766],[-89.270749,40.593136],[-88.931178,40.751967],[-88.712101,40.757444]]]}}, -{"type":"Feature","id":"17115","properties":{"name":"Macon"},"geometry":{"type":"Polygon","coordinates":[[[-88.805209,40.056395],[-88.744962,40.056395],[-88.744962,39.793502],[-88.761393,39.793502],[-88.810686,39.651102],[-89.024286,39.656579],[-89.215979,39.81541],[-89.215979,39.919472],[-89.144779,40.050919],[-88.805209,40.056395]]]}}, -{"type":"Feature","id":"17117","properties":{"name":"Macoupin"},"geometry":{"type":"Polygon","coordinates":[[[-89.758196,39.525132],[-89.703427,39.525132],[-89.69795,38.999346],[-90.147059,38.999346],[-90.147059,39.262239],[-90.152536,39.519655],[-89.927981,39.519655],[-89.758196,39.525132]]]}}, -{"type":"Feature","id":"17119","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-90.240167,38.999346],[-90.147059,38.999346],[-89.69795,38.999346],[-89.637704,38.999346],[-89.599365,38.74193],[-89.708904,38.654299],[-90.179921,38.659776],[-90.168967,38.774791],[-90.119674,38.807653],[-90.278506,38.922669],[-90.240167,38.999346]]]}}, -{"type":"Feature","id":"17121","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-88.777824,38.824084],[-88.69567,38.824084],[-88.701147,38.605006],[-88.701147,38.47356],[-88.914747,38.479037],[-89.144779,38.47356],[-89.144779,38.500944],[-89.139302,38.736453],[-88.777824,38.824084]]]}}, -{"type":"Feature","id":"17123","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-89.522688,41.146307],[-89.467918,41.146307],[-89.16121,41.102491],[-89.046194,40.927229],[-89.111917,40.927229],[-89.473395,40.921752],[-89.637704,40.976521],[-89.637704,41.146307],[-89.522688,41.146307]]]}}, -{"type":"Feature","id":"17125","properties":{"name":"Mason"},"geometry":{"type":"Polygon","coordinates":[[[-89.89512,40.434304],[-89.604842,40.319289],[-89.599365,40.122119],[-89.670565,40.160457],[-89.993705,40.105688],[-90.355183,40.122119],[-90.201828,40.182365],[-89.922504,40.434304],[-89.89512,40.434304]]]}}, -{"type":"Feature","id":"17127","properties":{"name":"Massac"},"geometry":{"type":"Polygon","coordinates":[[[-88.931178,37.301494],[-88.712101,37.334356],[-88.487546,37.065986],[-88.564223,37.082417],[-88.925701,37.224817],[-88.931178,37.301494]]]}}, -{"type":"Feature","id":"17129","properties":{"name":"Menard"},"geometry":{"type":"Polygon","coordinates":[[[-89.670565,40.160457],[-89.599365,40.122119],[-89.577457,39.974241],[-89.993705,39.903041],[-89.993705,40.105688],[-89.670565,40.160457]]]}}, -{"type":"Feature","id":"17131","properties":{"name":"Mercer"},"geometry":{"type":"Polygon","coordinates":[[[-91.050754,41.332523],[-90.43186,41.327046],[-90.437337,41.151784],[-90.437337,41.064153],[-90.667368,41.069629],[-90.787861,41.069629],[-90.946692,41.069629],[-90.946692,41.075106],[-91.072662,41.332523],[-91.050754,41.332523]]]}}, -{"type":"Feature","id":"17133","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-90.207305,38.47356],[-89.900597,38.22162],[-90.03752,38.22162],[-90.207305,38.090174],[-90.251121,38.128512],[-90.344229,38.385929],[-90.262075,38.522852],[-90.207305,38.47356]]]}}, -{"type":"Feature","id":"17135","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-89.588411,39.525132],[-89.533642,39.525132],[-89.139302,39.34987],[-89.139302,39.218424],[-89.248841,39.026731],[-89.637704,38.999346],[-89.69795,38.999346],[-89.703427,39.525132],[-89.588411,39.525132]]]}}, -{"type":"Feature","id":"17137","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-90.585214,39.875656],[-89.993705,39.87018],[-89.927981,39.519655],[-90.152536,39.519655],[-90.300413,39.519655],[-90.371614,39.667533],[-90.601645,39.788025],[-90.57426,39.837318],[-90.585214,39.875656]]]}}, -{"type":"Feature","id":"17139","properties":{"name":"Moultrie"},"geometry":{"type":"Polygon","coordinates":[[[-88.761393,39.793502],[-88.744962,39.793502],[-88.471115,39.793502],[-88.471115,39.651102],[-88.471115,39.448455],[-88.810686,39.651102],[-88.761393,39.793502]]]}}, -{"type":"Feature","id":"17141","properties":{"name":"Ogle"},"geometry":{"type":"Polygon","coordinates":[[[-89.281702,42.203356],[-88.942132,42.154064],[-88.942132,41.891171],[-89.544596,41.902124],[-89.632227,41.902124],[-89.686996,41.929509],[-89.686996,42.197879],[-89.396718,42.203356],[-89.281702,42.203356]]]}}, -{"type":"Feature","id":"17143","properties":{"name":"Peoria"},"geometry":{"type":"Polygon","coordinates":[[[-89.96632,40.976521],[-89.637704,40.976521],[-89.473395,40.921752],[-89.555549,40.74649],[-89.873212,40.510982],[-89.988228,40.713628],[-89.988228,40.976521],[-89.96632,40.976521]]]}}, -{"type":"Feature","id":"17145","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-89.593888,38.22162],[-89.144779,38.210667],[-89.128348,38.123036],[-89.177641,37.947773],[-89.566503,37.95325],[-89.593888,37.95325],[-89.593888,38.22162]]]}}, -{"type":"Feature","id":"17147","properties":{"name":"Piatt"},"geometry":{"type":"Polygon","coordinates":[[[-88.575177,40.28095],[-88.460161,40.28095],[-88.460161,39.881133],[-88.471115,39.793502],[-88.744962,39.793502],[-88.744962,40.056395],[-88.575177,40.28095]]]}}, -{"type":"Feature","id":"17149","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-90.919308,39.842795],[-90.57426,39.837318],[-90.601645,39.788025],[-90.579737,39.519655],[-90.612599,39.393686],[-90.935738,39.399163],[-91.176724,39.596333],[-91.30817,39.683964],[-91.36294,39.760641],[-90.919308,39.842795]]]}}, -{"type":"Feature","id":"17151","properties":{"name":"Pope"},"geometry":{"type":"Polygon","coordinates":[[[-88.410869,37.597249],[-88.416346,37.421987],[-88.487546,37.065986],[-88.712101,37.334356],[-88.706624,37.597249],[-88.410869,37.597249]]]}}, -{"type":"Feature","id":"17153","properties":{"name":"Pulaski"},"geometry":{"type":"Polygon","coordinates":[[[-89.046194,37.328879],[-88.931178,37.301494],[-88.925701,37.224817],[-88.936655,37.230294],[-89.172164,37.065986],[-89.248841,37.334356],[-89.046194,37.328879]]]}}, -{"type":"Feature","id":"17155","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-89.16121,41.310615],[-89.16121,41.102491],[-89.467918,41.146307],[-89.16121,41.310615]]]}}, -{"type":"Feature","id":"17157","properties":{"name":"Randolph"},"geometry":{"type":"Polygon","coordinates":[[[-90.03752,38.22162],[-89.900597,38.22162],[-89.703427,38.22162],[-89.593888,38.22162],[-89.593888,37.95325],[-89.676042,37.805373],[-89.938935,37.876573],[-90.207305,38.090174],[-90.03752,38.22162]]]}}, -{"type":"Feature","id":"17159","properties":{"name":"Richland"},"geometry":{"type":"Polygon","coordinates":[[[-87.90699,38.851469],[-87.912467,38.572145],[-87.956283,38.572145],[-88.005575,38.572145],[-88.147976,38.566668],[-88.252038,38.599529],[-88.257515,38.845992],[-87.945329,38.851469],[-87.90699,38.851469]]]}}, -{"type":"Feature","id":"17161","properties":{"name":"Rock Island"},"geometry":{"type":"Polygon","coordinates":[[[-90.240167,41.781632],[-90.185398,41.584462],[-90.43186,41.327046],[-91.050754,41.332523],[-91.072662,41.332523],[-91.072662,41.332523],[-90.787861,41.453015],[-90.316844,41.726862],[-90.240167,41.781632]]]}}, -{"type":"Feature","id":"17163","properties":{"name":"St. Clair"},"geometry":{"type":"Polygon","coordinates":[[[-90.179921,38.659776],[-89.708904,38.654299],[-89.703427,38.41879],[-89.703427,38.22162],[-89.900597,38.22162],[-90.207305,38.47356],[-90.262075,38.522852],[-90.256598,38.533806],[-90.179921,38.659776]]]}}, -{"type":"Feature","id":"17165","properties":{"name":"Saline"},"geometry":{"type":"Polygon","coordinates":[[[-88.4273,37.909435],[-88.37253,37.909435],[-88.378007,37.597249],[-88.410869,37.597249],[-88.706624,37.597249],[-88.706624,37.865619],[-88.706624,37.909435],[-88.4273,37.909435]]]}}, -{"type":"Feature","id":"17167","properties":{"name":"Sangamon"},"geometry":{"type":"Polygon","coordinates":[[[-89.489826,39.974241],[-89.215979,39.919472],[-89.215979,39.81541],[-89.254318,39.820887],[-89.533642,39.525132],[-89.588411,39.525132],[-89.703427,39.525132],[-89.758196,39.525132],[-89.927981,39.519655],[-89.993705,39.87018],[-89.993705,39.903041],[-89.577457,39.974241],[-89.489826,39.974241]]]}}, -{"type":"Feature","id":"17169","properties":{"name":"Schuyler"},"geometry":{"type":"Polygon","coordinates":[[[-90.908354,40.286427],[-90.448291,40.275473],[-90.201828,40.182365],[-90.355183,40.122119],[-90.514014,39.985195],[-90.913831,40.105688],[-90.913831,40.193319],[-90.908354,40.286427]]]}}, -{"type":"Feature","id":"17171","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-90.371614,39.667533],[-90.300413,39.519655],[-90.579737,39.519655],[-90.601645,39.788025],[-90.371614,39.667533]]]}}, -{"type":"Feature","id":"17173","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-89.024286,39.656579],[-88.810686,39.651102],[-88.471115,39.448455],[-88.471115,39.371778],[-88.471115,39.212947],[-88.580654,39.212947],[-88.805209,39.218424],[-89.139302,39.218424],[-89.139302,39.34987],[-89.024286,39.656579]]]}}, -{"type":"Feature","id":"17175","properties":{"name":"Stark"},"geometry":{"type":"Polygon","coordinates":[[[-89.856781,41.233938],[-89.637704,41.146307],[-89.637704,40.976521],[-89.96632,40.976521],[-89.988228,40.976521],[-89.982751,41.151784],[-89.856781,41.233938]]]}}, -{"type":"Feature","id":"17177","properties":{"name":"Stephenson"},"geometry":{"type":"Polygon","coordinates":[[[-89.927981,42.504588],[-89.84035,42.504588],[-89.402195,42.499111],[-89.396718,42.203356],[-89.686996,42.197879],[-89.917028,42.197879],[-89.927981,42.504588]]]}}, -{"type":"Feature","id":"17179","properties":{"name":"Tazewell"},"geometry":{"type":"Polygon","coordinates":[[[-89.50078,40.74649],[-89.270749,40.593136],[-89.265272,40.324766],[-89.604842,40.319289],[-89.89512,40.434304],[-89.922504,40.434304],[-89.873212,40.510982],[-89.555549,40.74649],[-89.50078,40.74649]]]}}, -{"type":"Feature","id":"17181","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-89.155733,37.602726],[-89.040717,37.597249],[-89.046194,37.328879],[-89.248841,37.334356],[-89.259795,37.334356],[-89.484349,37.334356],[-89.522688,37.564388],[-89.522688,37.569865],[-89.155733,37.602726]]]}}, -{"type":"Feature","id":"17183","properties":{"name":"Vermilion"},"geometry":{"type":"Polygon","coordinates":[[[-87.841267,40.489074],[-87.529082,40.489074],[-87.529082,40.47812],[-87.529082,40.149503],[-87.534558,39.881133],[-87.939852,39.881133],[-87.934375,40.401443],[-87.934375,40.483597],[-87.841267,40.489074]]]}}, -{"type":"Feature","id":"17185","properties":{"name":"Wabash"},"geometry":{"type":"Polygon","coordinates":[[[-87.912467,38.572145],[-87.649574,38.566668],[-87.742682,38.413313],[-87.972714,38.232574],[-87.989145,38.259959],[-87.956283,38.572145],[-87.912467,38.572145]]]}}, -{"type":"Feature","id":"17187","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-90.667368,41.069629],[-90.437337,41.064153],[-90.442814,40.713628],[-90.442814,40.625997],[-90.787861,40.636951],[-90.787861,41.069629],[-90.667368,41.069629]]]}}, -{"type":"Feature","id":"17189","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-89.320041,38.511898],[-89.144779,38.500944],[-89.144779,38.47356],[-89.144779,38.210667],[-89.593888,38.22162],[-89.703427,38.22162],[-89.703427,38.41879],[-89.320041,38.511898]]]}}, -{"type":"Feature","id":"17191","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-88.586131,38.605006],[-88.252038,38.599529],[-88.147976,38.566668],[-88.153453,38.254482],[-88.37253,38.254482],[-88.591608,38.254482],[-88.701147,38.254482],[-88.701147,38.47356],[-88.701147,38.605006],[-88.586131,38.605006]]]}}, -{"type":"Feature","id":"17193","properties":{"name":"White"},"geometry":{"type":"Polygon","coordinates":[[[-88.005575,38.259959],[-87.989145,38.259959],[-87.972714,38.232574],[-87.978191,38.232574],[-88.054868,37.88205],[-88.137022,37.909435],[-88.37253,37.909435],[-88.37253,38.254482],[-88.153453,38.254482],[-88.005575,38.259959]]]}}, -{"type":"Feature","id":"17195","properties":{"name":"Whiteside"},"geometry":{"type":"Polygon","coordinates":[[[-89.889643,41.929509],[-89.686996,41.929509],[-89.632227,41.902124],[-89.632227,41.584462],[-89.862258,41.584462],[-90.179921,41.584462],[-90.185398,41.584462],[-90.240167,41.781632],[-90.152536,41.929509],[-89.889643,41.929509]]]}}, -{"type":"Feature","id":"17197","properties":{"name":"Will"},"geometry":{"type":"Polygon","coordinates":[[[-88.03296,41.726862],[-88.027483,41.683047],[-87.523605,41.469446],[-87.529082,41.299661],[-87.786498,41.294184],[-88.246561,41.201076],[-88.252038,41.463969],[-88.262992,41.726862],[-88.03296,41.726862]]]}}, -{"type":"Feature","id":"17199","properties":{"name":"Williamson"},"geometry":{"type":"Polygon","coordinates":[[[-88.728531,37.865619],[-88.706624,37.865619],[-88.706624,37.597249],[-88.876409,37.597249],[-89.040717,37.597249],[-89.155733,37.602726],[-89.150256,37.860142],[-88.728531,37.865619]]]}}, -{"type":"Feature","id":"17201","properties":{"name":"Winnebago"},"geometry":{"type":"Polygon","coordinates":[[[-89.363857,42.499111],[-88.942132,42.493634],[-88.942132,42.154064],[-89.281702,42.203356],[-89.396718,42.203356],[-89.402195,42.499111],[-89.363857,42.499111]]]}}, -{"type":"Feature","id":"17203","properties":{"name":"Woodford"},"geometry":{"type":"Polygon","coordinates":[[[-89.111917,40.927229],[-89.046194,40.927229],[-88.931178,40.927229],[-88.931178,40.751967],[-89.270749,40.593136],[-89.50078,40.74649],[-89.555549,40.74649],[-89.473395,40.921752],[-89.111917,40.927229]]]}}, -{"type":"Feature","id":"18001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-84.878242,40.921752],[-84.801565,40.921752],[-84.801565,40.730059],[-84.801565,40.571228],[-85.069935,40.565751],[-85.075412,40.916275],[-84.878242,40.921752]]]}}, -{"type":"Feature","id":"18003","properties":{"name":"Allen"},"geometry":{"type":"Polygon","coordinates":[[[-84.845381,41.272276],[-84.801565,41.272276],[-84.801565,41.250368],[-84.801565,40.987475],[-84.801565,40.921752],[-84.878242,40.921752],[-85.075412,40.916275],[-85.108274,40.916275],[-85.338305,40.916275],[-85.332828,41.003906],[-85.305444,41.266799],[-85.190428,41.266799],[-84.845381,41.272276]]]}}, -{"type":"Feature","id":"18005","properties":{"name":"Bartholomew"},"geometry":{"type":"Polygon","coordinates":[[[-85.798368,39.34987],[-85.683353,39.34987],[-85.68883,39.130793],[-85.798368,39.070546],[-86.077692,39.048638],[-86.083169,39.344393],[-85.951723,39.34987],[-85.798368,39.34987]]]}}, -{"type":"Feature","id":"18007","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-87.326435,40.735536],[-87.266188,40.735536],[-87.096403,40.735536],[-87.096403,40.560274],[-87.096403,40.47812],[-87.452404,40.47812],[-87.529082,40.47812],[-87.529082,40.489074],[-87.523605,40.735536],[-87.326435,40.735536]]]}}, -{"type":"Feature","id":"18009","properties":{"name":"Blackford"},"geometry":{"type":"Polygon","coordinates":[[[-85.22329,40.565751],[-85.201382,40.565751],[-85.217813,40.379535],[-85.442367,40.379535],[-85.447844,40.565751],[-85.22329,40.565751]]]}}, -{"type":"Feature","id":"18011","properties":{"name":"Boone"},"geometry":{"type":"Polygon","coordinates":[[[-86.242001,40.182365],[-86.242001,39.924949],[-86.324155,39.924949],[-86.433693,39.924949],[-86.696587,39.924949],[-86.696587,40.176888],[-86.242001,40.182365]]]}}, -{"type":"Feature","id":"18013","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-86.252954,39.344393],[-86.083169,39.344393],[-86.077692,39.048638],[-86.318678,39.048638],[-86.378924,39.338916],[-86.252954,39.344393]]]}}, -{"type":"Feature","id":"18015","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-86.773264,40.560274],[-86.581571,40.735536],[-86.373447,40.560274],[-86.373447,40.434304],[-86.696587,40.434304],[-86.773264,40.560274]]]}}, -{"type":"Feature","id":"18017","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-86.581571,40.910798],[-86.466555,40.910798],[-86.1708,40.910798],[-86.165323,40.560274],[-86.373447,40.560274],[-86.581571,40.735536],[-86.581571,40.910798]]]}}, -{"type":"Feature","id":"18019","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-85.590245,38.605006],[-85.568337,38.605006],[-85.425936,38.588575],[-85.431413,38.522852],[-85.639537,38.380452],[-85.792891,38.287344],[-85.995538,38.41879],[-85.847661,38.561191],[-85.590245,38.605006]]]}}, -{"type":"Feature","id":"18021","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-87.200465,39.607286],[-87.014249,39.607286],[-86.937572,39.47584],[-87.052588,39.169131],[-87.211419,39.169131],[-87.238804,39.169131],[-87.238804,39.256762],[-87.200465,39.607286]]]}}, -{"type":"Feature","id":"18023","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-86.357016,40.434304],[-86.242001,40.374058],[-86.242001,40.215227],[-86.242001,40.182365],[-86.696587,40.176888],[-86.696587,40.215227],[-86.696587,40.434304],[-86.373447,40.434304],[-86.357016,40.434304]]]}}, -{"type":"Feature","id":"18025","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-86.307724,38.424267],[-86.252954,38.424267],[-86.307724,38.166851],[-86.461078,38.117559],[-86.570617,38.265436],[-86.680156,38.265436],[-86.680156,38.396883],[-86.307724,38.424267]]]}}, -{"type":"Feature","id":"18027","properties":{"name":"Daviess"},"geometry":{"type":"Polygon","coordinates":[[[-87.096403,38.906238],[-86.90471,38.906238],[-86.926618,38.506421],[-87.074495,38.517375],[-87.244281,38.54476],[-87.096403,38.906238]]]}}, -{"type":"Feature","id":"18029","properties":{"name":"Dearborn"},"geometry":{"type":"Polygon","coordinates":[[[-85.031597,39.306055],[-84.817996,39.306055],[-84.817996,39.103408],[-84.878242,39.032208],[-84.933012,39.0103],[-85.130182,38.950054],[-85.064458,39.306055],[-85.031597,39.306055]]]}}, -{"type":"Feature","id":"18031","properties":{"name":"Decatur"},"geometry":{"type":"Polygon","coordinates":[[[-85.299967,39.453932],[-85.29449,39.267716],[-85.442367,39.196516],[-85.68883,39.130793],[-85.683353,39.34987],[-85.628583,39.453932],[-85.299967,39.453932]]]}}, -{"type":"Feature","id":"18033","properties":{"name":"DeKalb"},"geometry":{"type":"Polygon","coordinates":[[[-84.916581,41.529692],[-84.807042,41.529692],[-84.801565,41.425631],[-84.801565,41.272276],[-84.845381,41.272276],[-85.190428,41.266799],[-85.195905,41.524216],[-84.916581,41.529692]]]}}, -{"type":"Feature","id":"18035","properties":{"name":"Delaware"},"geometry":{"type":"Polygon","coordinates":[[[-85.513567,40.379535],[-85.442367,40.379535],[-85.217813,40.379535],[-85.217813,40.308335],[-85.212336,40.078303],[-85.327352,40.078303],[-85.573814,40.078303],[-85.579291,40.379535],[-85.513567,40.379535]]]}}, -{"type":"Feature","id":"18037","properties":{"name":"Dubois"},"geometry":{"type":"Polygon","coordinates":[[[-86.680156,38.528329],[-86.680156,38.396883],[-86.680156,38.265436],[-86.789695,38.20519],[-86.866372,38.20519],[-87.019726,38.20519],[-87.074495,38.232574],[-87.074495,38.517375],[-86.926618,38.506421],[-86.680156,38.528329]]]}}, -{"type":"Feature","id":"18039","properties":{"name":"Elkhart"},"geometry":{"type":"Polygon","coordinates":[[[-85.990061,41.759724],[-85.792891,41.759724],[-85.661445,41.759724],[-85.655968,41.524216],[-85.655968,41.436584],[-86.061262,41.436584],[-86.061262,41.4804],[-86.061262,41.759724],[-85.990061,41.759724]]]}}, -{"type":"Feature","id":"18041","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-85.22329,39.788025],[-85.037074,39.716825],[-85.037074,39.525132],[-85.23972,39.525132],[-85.299967,39.525132],[-85.299967,39.788025],[-85.22329,39.788025]]]}}, -{"type":"Feature","id":"18043","properties":{"name":"Floyd"},"geometry":{"type":"Polygon","coordinates":[[[-86.011969,38.41879],[-85.995538,38.41879],[-85.792891,38.287344],[-85.90243,38.177805],[-86.033877,38.41879],[-86.011969,38.41879]]]}}, -{"type":"Feature","id":"18045","properties":{"name":"Fountain"},"geometry":{"type":"Polygon","coordinates":[[[-87.255235,40.297381],[-87.090926,40.368581],[-87.090926,40.215227],[-87.090926,39.952334],[-87.205942,39.952334],[-87.419543,39.952334],[-87.408589,40.127596],[-87.255235,40.297381]]]}}, -{"type":"Feature","id":"18047","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-85.23972,39.525132],[-85.037074,39.525132],[-84.817996,39.519655],[-84.817996,39.306055],[-85.031597,39.306055],[-85.064458,39.306055],[-85.09732,39.311532],[-85.29449,39.267716],[-85.299967,39.453932],[-85.299967,39.525132],[-85.23972,39.525132]]]}}, -{"type":"Feature","id":"18049","properties":{"name":"Fulton"},"geometry":{"type":"Polygon","coordinates":[[[-86.242001,41.173691],[-86.077692,41.173691],[-85.946246,41.042245],[-85.946246,40.998429],[-86.1708,40.910798],[-86.466555,40.910798],[-86.466555,41.173691],[-86.242001,41.173691]]]}}, -{"type":"Feature","id":"18051","properties":{"name":"Gibson"},"geometry":{"type":"Polygon","coordinates":[[[-87.605759,38.446175],[-87.463358,38.533806],[-87.315481,38.243528],[-87.468835,38.166851],[-87.687913,38.166851],[-87.972714,38.232574],[-87.978191,38.232574],[-87.972714,38.232574],[-87.742682,38.413313],[-87.605759,38.446175]]]}}, -{"type":"Feature","id":"18053","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-85.447844,40.653382],[-85.447844,40.565751],[-85.442367,40.379535],[-85.513567,40.379535],[-85.579291,40.379535],[-85.672399,40.379535],[-85.864092,40.379535],[-85.864092,40.40692],[-85.864092,40.565751],[-85.864092,40.653382],[-85.639537,40.653382],[-85.447844,40.653382]]]}}, -{"type":"Feature","id":"18055","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-87.211419,39.169131],[-87.052588,39.169131],[-86.685633,39.163654],[-86.680156,38.993869],[-86.680156,38.906238],[-86.756833,38.906238],[-86.90471,38.906238],[-87.096403,38.906238],[-87.238804,38.906238],[-87.238804,39.169131],[-87.211419,39.169131]]]}}, -{"type":"Feature","id":"18057","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-85.875046,40.220704],[-85.864092,40.220704],[-85.864092,39.94138],[-85.935292,39.924949],[-86.110554,39.924949],[-86.242001,39.924949],[-86.242001,40.182365],[-86.242001,40.215227],[-85.875046,40.220704]]]}}, -{"type":"Feature","id":"18059","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-85.617629,39.946857],[-85.573814,39.946857],[-85.595722,39.788025],[-85.63406,39.700394],[-85.951723,39.694917],[-85.935292,39.924949],[-85.864092,39.94138],[-85.617629,39.946857]]]}}, -{"type":"Feature","id":"18061","properties":{"name":"Harrison"},"geometry":{"type":"Polygon","coordinates":[[[-86.198185,38.424267],[-86.033877,38.41879],[-85.90243,38.177805],[-85.946246,38.00802],[-86.001015,37.997066],[-86.307724,38.166851],[-86.252954,38.424267],[-86.198185,38.424267]]]}}, -{"type":"Feature","id":"18063","properties":{"name":"Hendricks"},"geometry":{"type":"Polygon","coordinates":[[[-86.433693,39.924949],[-86.324155,39.924949],[-86.324155,39.629194],[-86.658248,39.601809],[-86.696587,39.864703],[-86.696587,39.924949],[-86.433693,39.924949]]]}}, -{"type":"Feature","id":"18065","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-85.327352,40.078303],[-85.212336,40.078303],[-85.201382,40.007103],[-85.22329,39.788025],[-85.299967,39.788025],[-85.321875,39.788025],[-85.595722,39.788025],[-85.573814,39.946857],[-85.573814,40.078303],[-85.327352,40.078303]]]}}, -{"type":"Feature","id":"18067","properties":{"name":"Howard"},"geometry":{"type":"Polygon","coordinates":[[[-85.875046,40.565751],[-85.864092,40.565751],[-85.864092,40.40692],[-86.242001,40.374058],[-86.357016,40.434304],[-86.373447,40.434304],[-86.373447,40.560274],[-86.165323,40.560274],[-85.875046,40.565751]]]}}, -{"type":"Feature","id":"18069","properties":{"name":"Huntington"},"geometry":{"type":"Polygon","coordinates":[[[-85.376644,41.003906],[-85.332828,41.003906],[-85.338305,40.916275],[-85.447844,40.653382],[-85.639537,40.653382],[-85.645014,41.003906],[-85.376644,41.003906]]]}}, -{"type":"Feature","id":"18071","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-85.798368,39.070546],[-85.792891,38.807653],[-85.885999,38.736453],[-86.274862,38.763838],[-86.318678,38.988392],[-86.318678,39.048638],[-86.077692,39.048638],[-85.798368,39.070546]]]}}, -{"type":"Feature","id":"18073","properties":{"name":"Jasper"},"geometry":{"type":"Polygon","coordinates":[[[-87.036157,41.255845],[-86.932095,41.239415],[-86.932095,41.173691],[-86.932095,40.910798],[-87.096403,40.735536],[-87.266188,40.735536],[-87.277142,41.21203],[-87.277142,41.217507],[-87.216896,41.239415],[-87.036157,41.255845]]]}}, -{"type":"Feature","id":"18075","properties":{"name":"Jay"},"geometry":{"type":"Polygon","coordinates":[[[-84.801565,40.571228],[-84.801565,40.35215],[-84.801565,40.308335],[-84.807042,40.308335],[-85.217813,40.308335],[-85.217813,40.379535],[-85.201382,40.565751],[-85.069935,40.565751],[-84.801565,40.571228]]]}}, -{"type":"Feature","id":"18077","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-85.299967,38.911715],[-85.201382,38.911715],[-85.201382,38.692637],[-85.332828,38.736453],[-85.425936,38.588575],[-85.568337,38.605006],[-85.683353,38.81313],[-85.442367,38.911715],[-85.299967,38.911715]]]}}, -{"type":"Feature","id":"18079","properties":{"name":"Jennings"},"geometry":{"type":"Polygon","coordinates":[[[-85.442367,39.196516],[-85.442367,38.911715],[-85.683353,38.81313],[-85.792891,38.807653],[-85.798368,39.070546],[-85.68883,39.130793],[-85.442367,39.196516]]]}}, -{"type":"Feature","id":"18081","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-85.97363,39.640148],[-85.951723,39.640148],[-85.951723,39.34987],[-86.083169,39.344393],[-86.252954,39.344393],[-86.247477,39.634671],[-85.97363,39.640148]]]}}, -{"type":"Feature","id":"18083","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-87.238804,38.906238],[-87.096403,38.906238],[-87.244281,38.54476],[-87.463358,38.533806],[-87.605759,38.446175],[-87.742682,38.413313],[-87.649574,38.566668],[-87.534558,38.851469],[-87.534558,38.900761],[-87.238804,38.906238]]]}}, -{"type":"Feature","id":"18085","properties":{"name":"Kosciusko"},"geometry":{"type":"Polygon","coordinates":[[[-85.655968,41.436584],[-85.650491,41.294184],[-85.683353,41.047722],[-85.946246,41.042245],[-86.077692,41.173691],[-86.061262,41.436584],[-85.655968,41.436584]]]}}, -{"type":"Feature","id":"18087","properties":{"name":"LaGrange"},"geometry":{"type":"Polygon","coordinates":[[[-85.371167,41.759724],[-85.29449,41.759724],[-85.195905,41.759724],[-85.195905,41.524216],[-85.655968,41.524216],[-85.661445,41.759724],[-85.371167,41.759724]]]}}, -{"type":"Feature","id":"18089","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-87.222373,41.6228],[-87.216896,41.239415],[-87.277142,41.217507],[-87.529082,41.168214],[-87.529082,41.299661],[-87.523605,41.469446],[-87.523605,41.710431],[-87.222373,41.6228]]]}}, -{"type":"Feature","id":"18091","properties":{"name":"LaPorte"},"geometry":{"type":"Polygon","coordinates":[[[-86.822556,41.759724],[-86.521325,41.759724],[-86.526801,41.431108],[-86.932095,41.239415],[-86.932095,41.710431],[-86.822556,41.759724]]]}}, -{"type":"Feature","id":"18093","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-86.680156,38.993869],[-86.318678,38.988392],[-86.274862,38.763838],[-86.307724,38.68716],[-86.685633,38.68716],[-86.680156,38.906238],[-86.680156,38.993869]]]}}, -{"type":"Feature","id":"18095","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-85.672399,40.379535],[-85.579291,40.379535],[-85.573814,40.078303],[-85.573814,39.946857],[-85.617629,39.946857],[-85.864092,39.94138],[-85.864092,40.220704],[-85.864092,40.379535],[-85.672399,40.379535]]]}}, -{"type":"Feature","id":"18097","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-86.110554,39.924949],[-85.935292,39.924949],[-85.951723,39.694917],[-85.951723,39.640148],[-85.97363,39.640148],[-86.247477,39.634671],[-86.324155,39.629194],[-86.324155,39.924949],[-86.242001,39.924949],[-86.110554,39.924949]]]}}, -{"type":"Feature","id":"18099","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-86.247477,41.4804],[-86.061262,41.4804],[-86.061262,41.436584],[-86.077692,41.173691],[-86.242001,41.173691],[-86.466555,41.173691],[-86.466555,41.431108],[-86.247477,41.4804]]]}}, -{"type":"Feature","id":"18101","properties":{"name":"Martin"},"geometry":{"type":"Polygon","coordinates":[[[-86.756833,38.906238],[-86.680156,38.906238],[-86.685633,38.68716],[-86.680156,38.528329],[-86.926618,38.506421],[-86.90471,38.906238],[-86.756833,38.906238]]]}}, -{"type":"Feature","id":"18103","properties":{"name":"Miami"},"geometry":{"type":"Polygon","coordinates":[[[-85.946246,40.998429],[-85.864092,40.653382],[-85.864092,40.565751],[-85.875046,40.565751],[-86.165323,40.560274],[-86.1708,40.910798],[-85.946246,40.998429]]]}}, -{"type":"Feature","id":"18105","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-86.630863,39.34987],[-86.378924,39.338916],[-86.318678,39.048638],[-86.318678,38.988392],[-86.680156,38.993869],[-86.685633,39.163654],[-86.630863,39.34987]]]}}, -{"type":"Feature","id":"18107","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-86.921141,40.215227],[-86.696587,40.215227],[-86.696587,40.176888],[-86.696587,39.924949],[-86.696587,39.864703],[-87.008772,39.864703],[-87.090926,39.952334],[-87.090926,40.215227],[-86.921141,40.215227]]]}}, -{"type":"Feature","id":"18109","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-86.247477,39.634671],[-86.252954,39.344393],[-86.378924,39.338916],[-86.630863,39.34987],[-86.685633,39.470363],[-86.658248,39.601809],[-86.324155,39.629194],[-86.247477,39.634671]]]}}, -{"type":"Feature","id":"18111","properties":{"name":"Newton"},"geometry":{"type":"Polygon","coordinates":[[[-87.277142,41.21203],[-87.266188,40.735536],[-87.326435,40.735536],[-87.523605,40.735536],[-87.523605,41.009383],[-87.529082,41.168214],[-87.277142,41.217507],[-87.277142,41.21203]]]}}, -{"type":"Feature","id":"18113","properties":{"name":"Noble"},"geometry":{"type":"Polygon","coordinates":[[[-85.195905,41.524216],[-85.190428,41.266799],[-85.305444,41.266799],[-85.650491,41.294184],[-85.655968,41.436584],[-85.655968,41.524216],[-85.195905,41.524216]]]}}, -{"type":"Feature","id":"18115","properties":{"name":"Ohio"},"geometry":{"type":"Polygon","coordinates":[[[-84.933012,39.0103],[-84.878242,39.032208],[-84.872765,38.900761],[-85.135659,38.928146],[-85.130182,38.950054],[-84.933012,39.0103]]]}}, -{"type":"Feature","id":"18117","properties":{"name":"Orange"},"geometry":{"type":"Polygon","coordinates":[[[-86.307724,38.68716],[-86.307724,38.424267],[-86.680156,38.396883],[-86.680156,38.528329],[-86.685633,38.68716],[-86.307724,38.68716]]]}}, -{"type":"Feature","id":"18119","properties":{"name":"Owen"},"geometry":{"type":"Polygon","coordinates":[[[-86.937572,39.47584],[-86.685633,39.470363],[-86.630863,39.34987],[-86.685633,39.163654],[-87.052588,39.169131],[-86.937572,39.47584]]]}}, -{"type":"Feature","id":"18121","properties":{"name":"Parke"},"geometry":{"type":"Polygon","coordinates":[[[-87.205942,39.952334],[-87.090926,39.952334],[-87.008772,39.864703],[-87.014249,39.607286],[-87.200465,39.607286],[-87.331912,39.607286],[-87.381204,39.607286],[-87.419543,39.952334],[-87.205942,39.952334]]]}}, -{"type":"Feature","id":"18123","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-86.570617,38.265436],[-86.461078,38.117559],[-86.488463,38.046358],[-86.652771,37.843712],[-86.811602,37.997066],[-86.789695,38.20519],[-86.680156,38.265436],[-86.570617,38.265436]]]}}, -{"type":"Feature","id":"18125","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-87.074495,38.517375],[-87.074495,38.232574],[-87.310004,38.243528],[-87.315481,38.243528],[-87.463358,38.533806],[-87.244281,38.54476],[-87.074495,38.517375]]]}}, -{"type":"Feature","id":"18127","properties":{"name":"Porter"},"geometry":{"type":"Polygon","coordinates":[[[-86.932095,41.710431],[-86.932095,41.239415],[-87.036157,41.255845],[-87.216896,41.239415],[-87.222373,41.6228],[-86.932095,41.710431]]]}}, -{"type":"Feature","id":"18129","properties":{"name":"Posey"},"geometry":{"type":"Polygon","coordinates":[[[-87.972714,38.232574],[-87.687913,38.166851],[-87.698867,37.898481],[-87.928898,37.903958],[-88.027483,37.799896],[-88.054868,37.88205],[-87.978191,38.232574],[-87.972714,38.232574]]]}}, -{"type":"Feature","id":"18131","properties":{"name":"Pulaski"},"geometry":{"type":"Polygon","coordinates":[[[-86.669202,41.173691],[-86.466555,41.173691],[-86.466555,40.910798],[-86.581571,40.910798],[-86.877326,40.910798],[-86.932095,40.910798],[-86.932095,41.173691],[-86.669202,41.173691]]]}}, -{"type":"Feature","id":"18133","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-87.008772,39.864703],[-86.696587,39.864703],[-86.658248,39.601809],[-86.685633,39.470363],[-86.937572,39.47584],[-87.014249,39.607286],[-87.008772,39.864703]]]}}, -{"type":"Feature","id":"18135","properties":{"name":"Randolph"},"geometry":{"type":"Polygon","coordinates":[[[-84.807042,40.308335],[-84.801565,40.308335],[-84.812519,40.007103],[-84.856335,40.007103],[-85.201382,40.007103],[-85.212336,40.078303],[-85.217813,40.308335],[-84.807042,40.308335]]]}}, -{"type":"Feature","id":"18137","properties":{"name":"Ripley"},"geometry":{"type":"Polygon","coordinates":[[[-85.09732,39.311532],[-85.064458,39.306055],[-85.130182,38.950054],[-85.135659,38.928146],[-85.201382,38.911715],[-85.299967,38.911715],[-85.442367,38.911715],[-85.442367,39.196516],[-85.29449,39.267716],[-85.09732,39.311532]]]}}, -{"type":"Feature","id":"18139","properties":{"name":"Rush"},"geometry":{"type":"Polygon","coordinates":[[[-85.321875,39.788025],[-85.299967,39.788025],[-85.299967,39.525132],[-85.299967,39.453932],[-85.628583,39.453932],[-85.63406,39.700394],[-85.595722,39.788025],[-85.321875,39.788025]]]}}, -{"type":"Feature","id":"18141","properties":{"name":"St. Joseph"},"geometry":{"type":"Polygon","coordinates":[[[-86.061262,41.759724],[-86.061262,41.4804],[-86.247477,41.4804],[-86.466555,41.431108],[-86.526801,41.431108],[-86.521325,41.759724],[-86.22557,41.759724],[-86.061262,41.759724]]]}}, -{"type":"Feature","id":"18143","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-85.683353,38.81313],[-85.568337,38.605006],[-85.590245,38.605006],[-85.847661,38.561191],[-85.885999,38.736453],[-85.792891,38.807653],[-85.683353,38.81313]]]}}, -{"type":"Feature","id":"18145","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-85.63406,39.700394],[-85.628583,39.453932],[-85.683353,39.34987],[-85.798368,39.34987],[-85.951723,39.34987],[-85.951723,39.640148],[-85.951723,39.694917],[-85.63406,39.700394]]]}}, -{"type":"Feature","id":"18147","properties":{"name":"Spencer"},"geometry":{"type":"Polygon","coordinates":[[[-86.866372,38.20519],[-86.789695,38.20519],[-86.811602,37.997066],[-86.981388,37.931343],[-87.266188,37.876573],[-87.019726,38.20519],[-86.866372,38.20519]]]}}, -{"type":"Feature","id":"18149","properties":{"name":"Starke"},"geometry":{"type":"Polygon","coordinates":[[[-86.466555,41.431108],[-86.466555,41.173691],[-86.669202,41.173691],[-86.932095,41.173691],[-86.932095,41.239415],[-86.526801,41.431108],[-86.466555,41.431108]]]}}, -{"type":"Feature","id":"18151","properties":{"name":"Steuben"},"geometry":{"type":"Polygon","coordinates":[[[-84.823473,41.759724],[-84.807042,41.694001],[-84.807042,41.529692],[-84.916581,41.529692],[-85.195905,41.524216],[-85.195905,41.759724],[-84.823473,41.759724]]]}}, -{"type":"Feature","id":"18153","properties":{"name":"Sullivan"},"geometry":{"type":"Polygon","coordinates":[[[-87.578374,39.256762],[-87.238804,39.256762],[-87.238804,39.169131],[-87.238804,38.906238],[-87.534558,38.900761],[-87.644097,39.158177],[-87.605759,39.256762],[-87.578374,39.256762]]]}}, -{"type":"Feature","id":"18155","properties":{"name":"Switzerland"},"geometry":{"type":"Polygon","coordinates":[[[-85.135659,38.928146],[-84.872765,38.900761],[-84.796088,38.856946],[-85.02612,38.763838],[-85.201382,38.692637],[-85.201382,38.911715],[-85.135659,38.928146]]]}}, -{"type":"Feature","id":"18157","properties":{"name":"Tippecanoe"},"geometry":{"type":"Polygon","coordinates":[[[-87.096403,40.560274],[-86.773264,40.560274],[-86.696587,40.434304],[-86.696587,40.215227],[-86.921141,40.215227],[-87.090926,40.215227],[-87.090926,40.368581],[-87.096403,40.47812],[-87.096403,40.560274]]]}}, -{"type":"Feature","id":"18159","properties":{"name":"Tipton"},"geometry":{"type":"Polygon","coordinates":[[[-85.864092,40.40692],[-85.864092,40.379535],[-85.864092,40.220704],[-85.875046,40.220704],[-86.242001,40.215227],[-86.242001,40.374058],[-85.864092,40.40692]]]}}, -{"type":"Feature","id":"18161","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-84.812519,39.727779],[-84.812519,39.568948],[-84.817996,39.519655],[-85.037074,39.525132],[-85.037074,39.716825],[-84.812519,39.727779]]]}}, -{"type":"Feature","id":"18163","properties":{"name":"Vanderburgh"},"geometry":{"type":"Polygon","coordinates":[[[-87.687913,38.166851],[-87.468835,38.166851],[-87.452404,37.942297],[-87.698867,37.898481],[-87.687913,38.166851]]]}}, -{"type":"Feature","id":"18165","properties":{"name":"Vermillion"},"geometry":{"type":"Polygon","coordinates":[[[-87.408589,40.127596],[-87.419543,39.952334],[-87.381204,39.607286],[-87.534558,39.607286],[-87.534558,39.881133],[-87.529082,40.149503],[-87.408589,40.127596]]]}}, -{"type":"Feature","id":"18167","properties":{"name":"Vigo"},"geometry":{"type":"Polygon","coordinates":[[[-87.331912,39.607286],[-87.200465,39.607286],[-87.238804,39.256762],[-87.578374,39.256762],[-87.605759,39.256762],[-87.529082,39.47584],[-87.534558,39.607286],[-87.381204,39.607286],[-87.331912,39.607286]]]}}, -{"type":"Feature","id":"18169","properties":{"name":"Wabash"},"geometry":{"type":"Polygon","coordinates":[[[-85.683353,41.047722],[-85.645014,41.003906],[-85.639537,40.653382],[-85.864092,40.653382],[-85.946246,40.998429],[-85.946246,41.042245],[-85.683353,41.047722]]]}}, -{"type":"Feature","id":"18171","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-87.452404,40.47812],[-87.096403,40.47812],[-87.090926,40.368581],[-87.255235,40.297381],[-87.408589,40.127596],[-87.529082,40.149503],[-87.529082,40.47812],[-87.452404,40.47812]]]}}, -{"type":"Feature","id":"18173","properties":{"name":"Warrick"},"geometry":{"type":"Polygon","coordinates":[[[-87.310004,38.243528],[-87.074495,38.232574],[-87.019726,38.20519],[-87.266188,37.876573],[-87.304527,37.898481],[-87.452404,37.942297],[-87.468835,38.166851],[-87.315481,38.243528],[-87.310004,38.243528]]]}}, -{"type":"Feature","id":"18175","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-86.274862,38.763838],[-85.885999,38.736453],[-85.847661,38.561191],[-85.995538,38.41879],[-86.011969,38.41879],[-86.033877,38.41879],[-86.198185,38.424267],[-86.252954,38.424267],[-86.307724,38.424267],[-86.307724,38.68716],[-86.274862,38.763838]]]}}, -{"type":"Feature","id":"18177","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-84.856335,40.007103],[-84.812519,40.007103],[-84.812519,39.919472],[-84.812519,39.727779],[-85.037074,39.716825],[-85.22329,39.788025],[-85.201382,40.007103],[-84.856335,40.007103]]]}}, -{"type":"Feature","id":"18179","properties":{"name":"Wells"},"geometry":{"type":"Polygon","coordinates":[[[-85.108274,40.916275],[-85.075412,40.916275],[-85.069935,40.565751],[-85.201382,40.565751],[-85.22329,40.565751],[-85.447844,40.565751],[-85.447844,40.653382],[-85.338305,40.916275],[-85.108274,40.916275]]]}}, -{"type":"Feature","id":"18181","properties":{"name":"White"},"geometry":{"type":"Polygon","coordinates":[[[-86.877326,40.910798],[-86.581571,40.910798],[-86.581571,40.735536],[-86.773264,40.560274],[-87.096403,40.560274],[-87.096403,40.735536],[-86.932095,40.910798],[-86.877326,40.910798]]]}}, -{"type":"Feature","id":"18183","properties":{"name":"Whitley"},"geometry":{"type":"Polygon","coordinates":[[[-85.650491,41.294184],[-85.305444,41.266799],[-85.332828,41.003906],[-85.376644,41.003906],[-85.645014,41.003906],[-85.683353,41.047722],[-85.650491,41.294184]]]}}, -{"type":"Feature","id":"19001","properties":{"name":"Adair"},"geometry":{"type":"Polygon","coordinates":[[[-94.660058,41.502308],[-94.24381,41.502308],[-94.24381,41.157261],[-94.468365,41.157261],[-94.698396,41.157261],[-94.698396,41.502308],[-94.660058,41.502308]]]}}, -{"type":"Feature","id":"19003","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-94.813412,41.157261],[-94.698396,41.157261],[-94.468365,41.157261],[-94.468365,40.899844],[-94.857228,40.899844],[-94.928428,40.899844],[-94.928428,41.157261],[-94.813412,41.157261]]]}}, -{"type":"Feature","id":"19005","properties":{"name":"Allamakee"},"geometry":{"type":"Polygon","coordinates":[[[-91.368417,43.501391],[-91.215062,43.501391],[-91.204109,43.424714],[-91.176724,43.079667],[-91.565587,43.079667],[-91.603925,43.079667],[-91.609402,43.501391],[-91.368417,43.501391]]]}}, -{"type":"Feature","id":"19007","properties":{"name":"Appanoose"},"geometry":{"type":"Polygon","coordinates":[[[-92.639067,40.899844],[-92.639067,40.593136],[-92.715744,40.587659],[-92.748606,40.587659],[-93.09913,40.582182],[-93.09913,40.899844],[-92.639067,40.899844]]]}}, -{"type":"Feature","id":"19009","properties":{"name":"Audubon"},"geometry":{"type":"Polygon","coordinates":[[[-95.092736,41.863786],[-94.742212,41.863786],[-94.698396,41.502308],[-95.043444,41.502308],[-95.092736,41.863786]]]}}, -{"type":"Feature","id":"19011","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-91.888726,42.296464],[-91.82848,42.296464],[-91.833957,41.863786],[-92.063988,41.863786],[-92.299497,41.863786],[-92.299497,42.296464],[-92.063988,42.296464],[-91.888726,42.296464]]]}}, -{"type":"Feature","id":"19013","properties":{"name":"Black Hawk"},"geometry":{"type":"Polygon","coordinates":[[[-92.469282,42.641511],[-92.080419,42.641511],[-92.063988,42.296464],[-92.299497,42.296464],[-92.535005,42.296464],[-92.551436,42.55388],[-92.556913,42.641511],[-92.469282,42.641511]]]}}, -{"type":"Feature","id":"19015","properties":{"name":"Boone"},"geometry":{"type":"Polygon","coordinates":[[[-93.931625,42.208833],[-93.696116,42.208833],[-93.696116,41.863786],[-93.772794,41.863786],[-93.816609,41.863786],[-94.161656,41.863786],[-94.167133,42.208833],[-93.931625,42.208833]]]}}, -{"type":"Feature","id":"19017","properties":{"name":"Bremer"},"geometry":{"type":"Polygon","coordinates":[[[-92.387128,42.909881],[-92.080419,42.904404],[-92.080419,42.641511],[-92.469282,42.641511],[-92.556913,42.641511],[-92.556913,42.904404],[-92.387128,42.909881]]]}}, -{"type":"Feature","id":"19019","properties":{"name":"Buchanan"},"geometry":{"type":"Polygon","coordinates":[[[-91.905157,42.641511],[-91.609402,42.641511],[-91.598448,42.296464],[-91.713464,42.296464],[-91.82848,42.296464],[-91.888726,42.296464],[-92.063988,42.296464],[-92.080419,42.641511],[-91.905157,42.641511]]]}}, -{"type":"Feature","id":"19021","properties":{"name":"Buena Vista"},"geometry":{"type":"Polygon","coordinates":[[[-95.251567,42.909881],[-94.911997,42.909881],[-94.911997,42.559357],[-95.388491,42.559357],[-95.388491,42.909881],[-95.251567,42.909881]]]}}, -{"type":"Feature","id":"19023","properties":{"name":"Butler"},"geometry":{"type":"Polygon","coordinates":[[[-93.022453,42.909881],[-92.556913,42.904404],[-92.556913,42.641511],[-92.551436,42.55388],[-92.907437,42.55388],[-93.02793,42.55388],[-93.022453,42.909881]]]}}, -{"type":"Feature","id":"19025","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-94.616242,42.559357],[-94.44098,42.559357],[-94.397165,42.208833],[-94.627196,42.208833],[-94.857228,42.208833],[-94.911997,42.559357],[-94.616242,42.559357]]]}}, -{"type":"Feature","id":"19027","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-95.092736,42.208833],[-94.857228,42.208833],[-94.627196,42.208833],[-94.627196,41.863786],[-94.742212,41.863786],[-95.092736,41.863786],[-95.092736,42.208833]]]}}, -{"type":"Feature","id":"19029","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-95.152983,41.507785],[-95.043444,41.502308],[-94.698396,41.502308],[-94.698396,41.157261],[-94.813412,41.157261],[-94.928428,41.157261],[-95.158459,41.157261],[-95.152983,41.507785]]]}}, -{"type":"Feature","id":"19031","properties":{"name":"Cedar"},"geometry":{"type":"Polygon","coordinates":[[[-91.012416,41.94594],[-90.8974,41.94594],[-90.8974,41.770678],[-90.8974,41.595416],[-91.30817,41.595416],[-91.368417,41.600893],[-91.368417,41.858309],[-91.368417,41.94594],[-91.012416,41.94594]]]}}, -{"type":"Feature","id":"19033","properties":{"name":"Cerro Gordo"},"geometry":{"type":"Polygon","coordinates":[[[-93.055314,43.254929],[-93.022453,43.254929],[-93.022453,43.211113],[-93.022453,42.909881],[-93.487993,42.909881],[-93.498947,42.909881],[-93.498947,43.254929],[-93.055314,43.254929]]]}}, -{"type":"Feature","id":"19035","properties":{"name":"Cherokee"},"geometry":{"type":"Polygon","coordinates":[[[-95.415876,42.909881],[-95.388491,42.909881],[-95.388491,42.559357],[-95.465168,42.559357],[-95.739015,42.559357],[-95.859508,42.559357],[-95.859508,42.909881],[-95.415876,42.909881]]]}}, -{"type":"Feature","id":"19037","properties":{"name":"Chickasaw"},"geometry":{"type":"Polygon","coordinates":[[[-92.255681,43.211113],[-92.080419,43.211113],[-92.080419,43.085144],[-92.080419,42.904404],[-92.387128,42.909881],[-92.556913,42.904404],[-92.556913,43.211113],[-92.255681,43.211113]]]}}, -{"type":"Feature","id":"19039","properties":{"name":"Clarke"},"geometry":{"type":"Polygon","coordinates":[[[-93.674209,41.162737],[-93.559193,41.162737],[-93.559193,40.899844],[-93.663255,40.899844],[-94.013779,40.894367],[-94.013779,41.157261],[-93.789224,41.162737],[-93.674209,41.162737]]]}}, -{"type":"Feature","id":"19041","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-95.169413,43.254929],[-94.911997,43.254929],[-94.911997,42.909881],[-95.251567,42.909881],[-95.388491,42.909881],[-95.388491,43.254929],[-95.169413,43.254929]]]}}, -{"type":"Feature","id":"19043","properties":{"name":"Clayton"},"geometry":{"type":"Polygon","coordinates":[[[-91.565587,43.079667],[-91.176724,43.079667],[-91.154816,42.986559],[-90.8974,42.674373],[-90.8974,42.657942],[-91.132908,42.646988],[-91.204109,42.646988],[-91.609402,42.641511],[-91.603925,43.079667],[-91.565587,43.079667]]]}}, -{"type":"Feature","id":"19045","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-90.366137,42.033571],[-90.152536,42.033571],[-90.152536,41.929509],[-90.240167,41.781632],[-90.316844,41.726862],[-90.798815,41.770678],[-90.8974,41.770678],[-90.8974,41.94594],[-90.8974,42.033571],[-90.366137,42.033571]]]}}, -{"type":"Feature","id":"19047","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-95.64043,42.208833],[-95.322768,42.208833],[-95.092736,42.208833],[-95.092736,41.863786],[-95.322768,41.863786],[-95.558276,41.863786],[-95.673292,41.863786],[-95.673292,42.208833],[-95.64043,42.208833]]]}}, -{"type":"Feature","id":"19049","properties":{"name":"Dallas"},"geometry":{"type":"Polygon","coordinates":[[[-93.816609,41.863786],[-93.789224,41.513262],[-93.822086,41.507785],[-94.24381,41.502308],[-94.282149,41.863786],[-94.161656,41.863786],[-93.816609,41.863786]]]}}, -{"type":"Feature","id":"19051","properties":{"name":"Davis"},"geometry":{"type":"Polygon","coordinates":[[[-92.179004,40.899844],[-92.179004,40.598613],[-92.348789,40.598613],[-92.452851,40.593136],[-92.639067,40.593136],[-92.639067,40.899844],[-92.179004,40.899844]]]}}, -{"type":"Feature","id":"19053","properties":{"name":"Decatur"},"geometry":{"type":"Polygon","coordinates":[[[-93.663255,40.899844],[-93.559193,40.899844],[-93.559193,40.582182],[-93.772794,40.576705],[-94.013779,40.571228],[-94.013779,40.894367],[-93.663255,40.899844]]]}}, -{"type":"Feature","id":"19055","properties":{"name":"Delaware"},"geometry":{"type":"Polygon","coordinates":[[[-91.204109,42.646988],[-91.132908,42.646988],[-91.127431,42.296464],[-91.36294,42.296464],[-91.598448,42.296464],[-91.609402,42.641511],[-91.204109,42.646988]]]}}, -{"type":"Feature","id":"19057","properties":{"name":"Des Moines"},"geometry":{"type":"Polygon","coordinates":[[[-91.324601,41.075106],[-90.946692,41.075106],[-90.946692,41.069629],[-91.111001,40.697198],[-91.406755,40.812213],[-91.368417,41.075106],[-91.324601,41.075106]]]}}, -{"type":"Feature","id":"19059","properties":{"name":"Dickinson"},"geometry":{"type":"Polygon","coordinates":[[[-95.092736,43.501391],[-94.917474,43.501391],[-94.911997,43.254929],[-95.169413,43.254929],[-95.388491,43.254929],[-95.388491,43.501391],[-95.092736,43.501391]]]}}, -{"type":"Feature","id":"19061","properties":{"name":"Dubuque"},"geometry":{"type":"Polygon","coordinates":[[[-90.8974,42.657942],[-90.8974,42.674373],[-90.639984,42.510065],[-90.475675,42.384095],[-90.8974,42.296464],[-91.127431,42.296464],[-91.132908,42.646988],[-90.8974,42.657942]]]}}, -{"type":"Feature","id":"19063","properties":{"name":"Emmet"},"geometry":{"type":"Polygon","coordinates":[[[-94.676489,43.501391],[-94.44098,43.501391],[-94.44098,43.254929],[-94.588858,43.254929],[-94.911997,43.254929],[-94.917474,43.501391],[-94.851751,43.501391],[-94.676489,43.501391]]]}}, -{"type":"Feature","id":"19065","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-92.080419,43.085144],[-91.603925,43.079667],[-91.609402,42.641511],[-91.905157,42.641511],[-92.080419,42.641511],[-92.080419,42.904404],[-92.080419,43.085144]]]}}, -{"type":"Feature","id":"19067","properties":{"name":"Floyd"},"geometry":{"type":"Polygon","coordinates":[[[-92.797898,43.211113],[-92.556913,43.211113],[-92.556913,42.904404],[-93.022453,42.909881],[-93.022453,43.211113],[-92.797898,43.211113]]]}}, -{"type":"Feature","id":"19069","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-93.487993,42.909881],[-93.022453,42.909881],[-93.02793,42.55388],[-93.263438,42.559357],[-93.498947,42.559357],[-93.498947,42.909881],[-93.487993,42.909881]]]}}, -{"type":"Feature","id":"19071","properties":{"name":"Fremont"},"geometry":{"type":"Polygon","coordinates":[[[-95.519938,40.899844],[-95.383014,40.899844],[-95.37206,40.582182],[-95.7664,40.587659],[-95.832123,40.784829],[-95.815692,40.899844],[-95.519938,40.899844]]]}}, -{"type":"Feature","id":"19073","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-94.167133,42.208833],[-94.161656,41.863786],[-94.282149,41.863786],[-94.484796,41.863786],[-94.627196,41.863786],[-94.627196,42.208833],[-94.397165,42.208833],[-94.167133,42.208833]]]}}, -{"type":"Feature","id":"19075","properties":{"name":"Grundy"},"geometry":{"type":"Polygon","coordinates":[[[-92.907437,42.55388],[-92.551436,42.55388],[-92.535005,42.296464],[-92.765037,42.208833],[-92.77599,42.208833],[-93.000545,42.208833],[-93.02793,42.55388],[-92.907437,42.55388]]]}}, -{"type":"Feature","id":"19077","properties":{"name":"Guthrie"},"geometry":{"type":"Polygon","coordinates":[[[-94.484796,41.863786],[-94.282149,41.863786],[-94.24381,41.502308],[-94.660058,41.502308],[-94.698396,41.502308],[-94.742212,41.863786],[-94.627196,41.863786],[-94.484796,41.863786]]]}}, -{"type":"Feature","id":"19079","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-93.893286,42.559357],[-93.498947,42.559357],[-93.460608,42.208833],[-93.696116,42.208833],[-93.931625,42.208833],[-93.969963,42.559357],[-93.893286,42.559357]]]}}, -{"type":"Feature","id":"19081","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-93.570147,43.254929],[-93.498947,43.254929],[-93.498947,42.909881],[-93.526331,42.909881],[-93.969963,42.909881],[-93.969963,43.254929],[-93.570147,43.254929]]]}}, -{"type":"Feature","id":"19083","properties":{"name":"Hardin"},"geometry":{"type":"Polygon","coordinates":[[[-93.263438,42.559357],[-93.02793,42.55388],[-93.000545,42.208833],[-93.230576,42.208833],[-93.362023,42.208833],[-93.460608,42.208833],[-93.498947,42.559357],[-93.263438,42.559357]]]}}, -{"type":"Feature","id":"19085","properties":{"name":"Harrison"},"geometry":{"type":"Polygon","coordinates":[[[-96.122401,41.863786],[-95.673292,41.863786],[-95.558276,41.863786],[-95.49803,41.507785],[-95.848554,41.507785],[-95.996431,41.507785],[-96.122401,41.683047],[-96.138832,41.863786],[-96.122401,41.863786]]]}}, -{"type":"Feature","id":"19087","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-91.598448,41.162737],[-91.483432,41.162737],[-91.368417,41.075106],[-91.406755,40.812213],[-91.603925,40.812213],[-91.718941,40.812213],[-91.718941,40.899844],[-91.713464,41.162737],[-91.598448,41.162737]]]}}, -{"type":"Feature","id":"19089","properties":{"name":"Howard"},"geometry":{"type":"Polygon","coordinates":[[[-92.080419,43.501391],[-92.080419,43.211113],[-92.255681,43.211113],[-92.556913,43.211113],[-92.551436,43.501391],[-92.447374,43.501391],[-92.080419,43.501391]]]}}, -{"type":"Feature","id":"19091","properties":{"name":"Humboldt"},"geometry":{"type":"Polygon","coordinates":[[[-94.090456,42.909881],[-93.969963,42.909881],[-93.969963,42.646988],[-94.44098,42.646988],[-94.44098,42.909881],[-94.090456,42.909881]]]}}, -{"type":"Feature","id":"19093","properties":{"name":"Ida"},"geometry":{"type":"Polygon","coordinates":[[[-95.465168,42.559357],[-95.388491,42.559357],[-95.322768,42.208833],[-95.64043,42.208833],[-95.673292,42.208833],[-95.739015,42.559357],[-95.465168,42.559357]]]}}, -{"type":"Feature","id":"19095","properties":{"name":"Iowa"},"geometry":{"type":"Polygon","coordinates":[[[-92.063988,41.863786],[-91.833957,41.863786],[-91.82848,41.513262],[-91.943495,41.513262],[-92.299497,41.507785],[-92.299497,41.863786],[-92.063988,41.863786]]]}}, -{"type":"Feature","id":"19097","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-90.475675,42.384095],[-90.316844,42.192402],[-90.152536,42.033571],[-90.366137,42.033571],[-90.8974,42.033571],[-90.8974,42.296464],[-90.475675,42.384095]]]}}, -{"type":"Feature","id":"19099","properties":{"name":"Jasper"},"geometry":{"type":"Polygon","coordinates":[[[-93.268915,41.863786],[-93.230576,41.863786],[-92.765037,41.863786],[-92.754083,41.507785],[-92.869098,41.507785],[-93.329161,41.507785],[-93.345592,41.863786],[-93.268915,41.863786]]]}}, -{"type":"Feature","id":"19101","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-91.943495,41.162737],[-91.713464,41.162737],[-91.718941,40.899844],[-92.118758,40.899844],[-92.179004,40.899844],[-92.179004,41.162737],[-91.943495,41.162737]]]}}, -{"type":"Feature","id":"19103","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-91.664172,41.863786],[-91.368417,41.858309],[-91.368417,41.600893],[-91.368417,41.425631],[-91.483432,41.425631],[-91.790141,41.513262],[-91.82848,41.513262],[-91.833957,41.863786],[-91.664172,41.863786]]]}}, -{"type":"Feature","id":"19105","properties":{"name":"Jones"},"geometry":{"type":"Polygon","coordinates":[[[-91.36294,42.296464],[-91.127431,42.296464],[-90.8974,42.296464],[-90.8974,42.033571],[-90.8974,41.94594],[-91.012416,41.94594],[-91.368417,41.94594],[-91.36294,42.296464]]]}}, -{"type":"Feature","id":"19107","properties":{"name":"Keokuk"},"geometry":{"type":"Polygon","coordinates":[[[-91.943495,41.513262],[-91.943495,41.162737],[-92.179004,41.162737],[-92.261158,41.162737],[-92.409035,41.162737],[-92.414512,41.507785],[-92.299497,41.507785],[-91.943495,41.513262]]]}}, -{"type":"Feature","id":"19109","properties":{"name":"Kossuth"},"geometry":{"type":"Polygon","coordinates":[[[-94.249287,43.501391],[-93.969963,43.501391],[-93.969963,43.254929],[-93.969963,42.909881],[-94.090456,42.909881],[-94.44098,42.909881],[-94.44098,43.254929],[-94.44098,43.501391],[-94.249287,43.501391]]]}}, -{"type":"Feature","id":"19111","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-91.603925,40.812213],[-91.406755,40.812213],[-91.111001,40.697198],[-91.187678,40.636951],[-91.417709,40.379535],[-91.718941,40.598613],[-91.718941,40.812213],[-91.603925,40.812213]]]}}, -{"type":"Feature","id":"19113","properties":{"name":"Linn"},"geometry":{"type":"Polygon","coordinates":[[[-91.713464,42.296464],[-91.598448,42.296464],[-91.36294,42.296464],[-91.368417,41.94594],[-91.368417,41.858309],[-91.664172,41.863786],[-91.833957,41.863786],[-91.82848,42.296464],[-91.713464,42.296464]]]}}, -{"type":"Feature","id":"19115","properties":{"name":"Louisa"},"geometry":{"type":"Polygon","coordinates":[[[-91.483432,41.425631],[-91.368417,41.425631],[-91.072662,41.332523],[-91.072662,41.332523],[-90.946692,41.075106],[-91.324601,41.075106],[-91.368417,41.075106],[-91.483432,41.162737],[-91.483432,41.425631]]]}}, -{"type":"Feature","id":"19117","properties":{"name":"Lucas"},"geometry":{"type":"Polygon","coordinates":[[[-93.09913,41.162737],[-93.09913,40.899844],[-93.559193,40.899844],[-93.559193,41.162737],[-93.329161,41.162737],[-93.09913,41.162737]]]}}, -{"type":"Feature","id":"19119","properties":{"name":"Lyon"},"geometry":{"type":"Polygon","coordinates":[[[-96.451017,43.501391],[-96.051201,43.501391],[-95.859508,43.501391],[-95.859508,43.254929],[-96.555079,43.260406],[-96.598895,43.501391],[-96.451017,43.501391]]]}}, -{"type":"Feature","id":"19121","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-93.822086,41.507785],[-93.789224,41.513262],[-93.789224,41.162737],[-94.013779,41.157261],[-94.24381,41.157261],[-94.24381,41.502308],[-93.822086,41.507785]]]}}, -{"type":"Feature","id":"19123","properties":{"name":"Mahaska"},"geometry":{"type":"Polygon","coordinates":[[[-92.458328,41.507785],[-92.414512,41.507785],[-92.409035,41.162737],[-92.639067,41.162737],[-92.655498,41.162737],[-92.869098,41.162737],[-92.869098,41.507785],[-92.754083,41.507785],[-92.458328,41.507785]]]}}, -{"type":"Feature","id":"19125","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-92.869098,41.507785],[-92.869098,41.162737],[-93.09913,41.162737],[-93.329161,41.162737],[-93.329161,41.491354],[-93.329161,41.507785],[-92.869098,41.507785]]]}}, -{"type":"Feature","id":"19127","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-92.77599,42.208833],[-92.765037,42.208833],[-92.765037,41.863786],[-93.230576,41.863786],[-93.230576,42.208833],[-93.000545,42.208833],[-92.77599,42.208833]]]}}, -{"type":"Feature","id":"19129","properties":{"name":"Mills"},"geometry":{"type":"Polygon","coordinates":[[[-95.673292,41.157261],[-95.383014,41.157261],[-95.383014,40.899844],[-95.519938,40.899844],[-95.815692,40.899844],[-95.881416,41.053199],[-95.881416,41.157261],[-95.673292,41.157261]]]}}, -{"type":"Feature","id":"19131","properties":{"name":"Mitchell"},"geometry":{"type":"Polygon","coordinates":[[[-92.551436,43.501391],[-92.556913,43.211113],[-92.797898,43.211113],[-93.022453,43.211113],[-93.022453,43.254929],[-93.022453,43.501391],[-92.551436,43.501391]]]}}, -{"type":"Feature","id":"19133","properties":{"name":"Monona"},"geometry":{"type":"Polygon","coordinates":[[[-96.133355,42.21431],[-95.673292,42.208833],[-95.673292,41.863786],[-96.122401,41.863786],[-96.138832,41.863786],[-96.270278,42.044525],[-96.357909,42.21431],[-96.133355,42.21431]]]}}, -{"type":"Feature","id":"19135","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-92.655498,41.162737],[-92.639067,41.162737],[-92.639067,40.899844],[-93.09913,40.899844],[-93.09913,41.162737],[-92.869098,41.162737],[-92.655498,41.162737]]]}}, -{"type":"Feature","id":"19137","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-95.267998,41.157261],[-95.158459,41.157261],[-94.928428,41.157261],[-94.928428,40.899844],[-95.289906,40.899844],[-95.383014,40.899844],[-95.383014,41.157261],[-95.267998,41.157261]]]}}, -{"type":"Feature","id":"19139","properties":{"name":"Muscatine"},"geometry":{"type":"Polygon","coordinates":[[[-91.30817,41.595416],[-90.8974,41.595416],[-90.787861,41.453015],[-91.072662,41.332523],[-91.368417,41.425631],[-91.368417,41.600893],[-91.30817,41.595416]]]}}, -{"type":"Feature","id":"19141","properties":{"name":"O'Brien"},"geometry":{"type":"Polygon","coordinates":[[[-95.574707,43.254929],[-95.388491,43.254929],[-95.388491,42.909881],[-95.415876,42.909881],[-95.859508,42.909881],[-95.859508,43.254929],[-95.574707,43.254929]]]}}, -{"type":"Feature","id":"19143","properties":{"name":"Osceola"},"geometry":{"type":"Polygon","coordinates":[[[-95.454214,43.501391],[-95.388491,43.501391],[-95.388491,43.254929],[-95.574707,43.254929],[-95.859508,43.254929],[-95.859508,43.501391],[-95.454214,43.501391]]]}}, -{"type":"Feature","id":"19145","properties":{"name":"Page"},"geometry":{"type":"Polygon","coordinates":[[[-95.289906,40.899844],[-94.928428,40.899844],[-94.917474,40.576705],[-95.163936,40.576705],[-95.202275,40.576705],[-95.37206,40.582182],[-95.383014,40.899844],[-95.289906,40.899844]]]}}, -{"type":"Feature","id":"19147","properties":{"name":"Palo Alto"},"geometry":{"type":"Polygon","coordinates":[[[-94.588858,43.254929],[-94.44098,43.254929],[-94.44098,42.909881],[-94.911997,42.909881],[-94.911997,43.254929],[-94.588858,43.254929]]]}}, -{"type":"Feature","id":"19149","properties":{"name":"Plymouth"},"geometry":{"type":"Polygon","coordinates":[[[-96.17717,42.909881],[-95.859508,42.909881],[-95.859508,42.559357],[-96.50031,42.559357],[-96.538648,42.909881],[-96.17717,42.909881]]]}}, -{"type":"Feature","id":"19151","properties":{"name":"Pocahontas"},"geometry":{"type":"Polygon","coordinates":[[[-94.44098,42.909881],[-94.44098,42.646988],[-94.44098,42.559357],[-94.616242,42.559357],[-94.911997,42.559357],[-94.911997,42.909881],[-94.44098,42.909881]]]}}, -{"type":"Feature","id":"19153","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-93.772794,41.863786],[-93.696116,41.863786],[-93.345592,41.863786],[-93.329161,41.507785],[-93.329161,41.491354],[-93.70707,41.513262],[-93.789224,41.513262],[-93.816609,41.863786],[-93.772794,41.863786]]]}}, -{"type":"Feature","id":"19155","properties":{"name":"Pottawattamie"},"geometry":{"type":"Polygon","coordinates":[[[-95.848554,41.507785],[-95.49803,41.507785],[-95.152983,41.507785],[-95.158459,41.157261],[-95.267998,41.157261],[-95.383014,41.157261],[-95.673292,41.157261],[-95.881416,41.157261],[-95.925231,41.190122],[-95.936185,41.392769],[-95.996431,41.507785],[-95.848554,41.507785]]]}}, -{"type":"Feature","id":"19157","properties":{"name":"Poweshiek"},"geometry":{"type":"Polygon","coordinates":[[[-92.299497,41.863786],[-92.299497,41.507785],[-92.414512,41.507785],[-92.458328,41.507785],[-92.754083,41.507785],[-92.765037,41.863786],[-92.299497,41.863786]]]}}, -{"type":"Feature","id":"19159","properties":{"name":"Ringgold"},"geometry":{"type":"Polygon","coordinates":[[[-94.358826,40.899844],[-94.013779,40.894367],[-94.013779,40.571228],[-94.232857,40.571228],[-94.287626,40.571228],[-94.473842,40.571228],[-94.468365,40.899844],[-94.358826,40.899844]]]}}, -{"type":"Feature","id":"19161","properties":{"name":"Sac"},"geometry":{"type":"Polygon","coordinates":[[[-95.388491,42.559357],[-94.911997,42.559357],[-94.857228,42.208833],[-95.092736,42.208833],[-95.322768,42.208833],[-95.388491,42.559357]]]}}, -{"type":"Feature","id":"19163","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-90.798815,41.770678],[-90.316844,41.726862],[-90.787861,41.453015],[-90.8974,41.595416],[-90.8974,41.770678],[-90.798815,41.770678]]]}}, -{"type":"Feature","id":"19165","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-95.322768,41.863786],[-95.092736,41.863786],[-95.043444,41.502308],[-95.152983,41.507785],[-95.49803,41.507785],[-95.558276,41.863786],[-95.322768,41.863786]]]}}, -{"type":"Feature","id":"19167","properties":{"name":"Sioux"},"geometry":{"type":"Polygon","coordinates":[[[-96.555079,43.260406],[-95.859508,43.254929],[-95.859508,42.909881],[-96.17717,42.909881],[-96.538648,42.909881],[-96.456494,43.085144],[-96.555079,43.260406]]]}}, -{"type":"Feature","id":"19169","properties":{"name":"Story"},"geometry":{"type":"Polygon","coordinates":[[[-93.362023,42.208833],[-93.230576,42.208833],[-93.230576,41.863786],[-93.268915,41.863786],[-93.345592,41.863786],[-93.696116,41.863786],[-93.696116,42.208833],[-93.460608,42.208833],[-93.362023,42.208833]]]}}, -{"type":"Feature","id":"19171","properties":{"name":"Tama"},"geometry":{"type":"Polygon","coordinates":[[[-92.299497,42.296464],[-92.299497,41.863786],[-92.765037,41.863786],[-92.765037,42.208833],[-92.535005,42.296464],[-92.299497,42.296464]]]}}, -{"type":"Feature","id":"19173","properties":{"name":"Taylor"},"geometry":{"type":"Polygon","coordinates":[[[-94.857228,40.899844],[-94.468365,40.899844],[-94.473842,40.571228],[-94.632673,40.571228],[-94.917474,40.576705],[-94.928428,40.899844],[-94.857228,40.899844]]]}}, -{"type":"Feature","id":"19175","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-94.468365,41.157261],[-94.24381,41.157261],[-94.013779,41.157261],[-94.013779,40.894367],[-94.358826,40.899844],[-94.468365,40.899844],[-94.468365,41.157261]]]}}, -{"type":"Feature","id":"19177","properties":{"name":"Van Buren"},"geometry":{"type":"Polygon","coordinates":[[[-92.118758,40.899844],[-91.718941,40.899844],[-91.718941,40.812213],[-91.718941,40.598613],[-91.833957,40.609566],[-91.943495,40.60409],[-92.179004,40.598613],[-92.179004,40.899844],[-92.118758,40.899844]]]}}, -{"type":"Feature","id":"19179","properties":{"name":"Wapello"},"geometry":{"type":"Polygon","coordinates":[[[-92.261158,41.162737],[-92.179004,41.162737],[-92.179004,40.899844],[-92.639067,40.899844],[-92.639067,41.162737],[-92.409035,41.162737],[-92.261158,41.162737]]]}}, -{"type":"Feature","id":"19181","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-93.70707,41.513262],[-93.329161,41.491354],[-93.329161,41.162737],[-93.559193,41.162737],[-93.674209,41.162737],[-93.789224,41.162737],[-93.789224,41.513262],[-93.70707,41.513262]]]}}, -{"type":"Feature","id":"19183","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-91.790141,41.513262],[-91.483432,41.425631],[-91.483432,41.162737],[-91.598448,41.162737],[-91.713464,41.162737],[-91.943495,41.162737],[-91.943495,41.513262],[-91.82848,41.513262],[-91.790141,41.513262]]]}}, -{"type":"Feature","id":"19185","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-93.09913,40.899844],[-93.09913,40.582182],[-93.372977,40.582182],[-93.526331,40.582182],[-93.559193,40.582182],[-93.559193,40.899844],[-93.09913,40.899844]]]}}, -{"type":"Feature","id":"19187","properties":{"name":"Webster"},"geometry":{"type":"Polygon","coordinates":[[[-94.44098,42.646988],[-93.969963,42.646988],[-93.969963,42.559357],[-93.931625,42.208833],[-94.167133,42.208833],[-94.397165,42.208833],[-94.44098,42.559357],[-94.44098,42.646988]]]}}, -{"type":"Feature","id":"19189","properties":{"name":"Winnebago"},"geometry":{"type":"Polygon","coordinates":[[[-93.646824,43.501391],[-93.498947,43.501391],[-93.498947,43.254929],[-93.570147,43.254929],[-93.969963,43.254929],[-93.969963,43.501391],[-93.646824,43.501391]]]}}, -{"type":"Feature","id":"19191","properties":{"name":"Winneshiek"},"geometry":{"type":"Polygon","coordinates":[[[-91.850387,43.501391],[-91.729895,43.501391],[-91.609402,43.501391],[-91.603925,43.079667],[-92.080419,43.085144],[-92.080419,43.211113],[-92.080419,43.501391],[-91.850387,43.501391]]]}}, -{"type":"Feature","id":"19193","properties":{"name":"Woodbury"},"geometry":{"type":"Polygon","coordinates":[[[-96.50031,42.559357],[-95.859508,42.559357],[-95.739015,42.559357],[-95.673292,42.208833],[-96.133355,42.21431],[-96.357909,42.21431],[-96.357909,42.274556],[-96.44554,42.488157],[-96.50031,42.559357]]]}}, -{"type":"Feature","id":"19195","properties":{"name":"Worth"},"geometry":{"type":"Polygon","coordinates":[[[-93.022453,43.501391],[-93.022453,43.254929],[-93.055314,43.254929],[-93.498947,43.254929],[-93.498947,43.501391],[-93.049837,43.501391],[-93.022453,43.501391]]]}}, -{"type":"Feature","id":"19197","properties":{"name":"Wright"},"geometry":{"type":"Polygon","coordinates":[[[-93.526331,42.909881],[-93.498947,42.909881],[-93.498947,42.559357],[-93.893286,42.559357],[-93.969963,42.559357],[-93.969963,42.646988],[-93.969963,42.909881],[-93.526331,42.909881]]]}}, -{"type":"Feature","id":"20001","properties":{"name":"Allen"},"geometry":{"type":"Polygon","coordinates":[[[-95.465168,38.040881],[-95.076305,38.035405],[-95.087259,37.734173],[-95.399445,37.734173],[-95.525414,37.734173],[-95.519938,38.040881],[-95.465168,38.040881]]]}}, -{"type":"Feature","id":"20003","properties":{"name":"Anderson"},"geometry":{"type":"Polygon","coordinates":[[[-95.235137,38.391406],[-95.065351,38.391406],[-95.076305,38.035405],[-95.465168,38.040881],[-95.519938,38.040881],[-95.508984,38.391406],[-95.235137,38.391406]]]}}, -{"type":"Feature","id":"20005","properties":{"name":"Atchison"},"geometry":{"type":"Polygon","coordinates":[[[-95.393968,39.651102],[-95.339199,39.651102],[-95.054398,39.623717],[-95.10369,39.530609],[-94.966767,39.42107],[-95.065351,39.42107],[-95.180367,39.42107],[-95.465168,39.42107],[-95.56923,39.42107],[-95.563753,39.651102],[-95.393968,39.651102]]]}}, -{"type":"Feature","id":"20007","properties":{"name":"Barber"},"geometry":{"type":"Polygon","coordinates":[[[-98.482962,37.47128],[-98.466531,37.47128],[-98.351516,37.383649],[-98.346039,37.000263],[-98.543209,37.000263],[-99.003272,37.000263],[-99.014225,37.383649],[-99.014225,37.47128],[-98.482962,37.47128]]]}}, -{"type":"Feature","id":"20009","properties":{"name":"Barton"},"geometry":{"type":"Polygon","coordinates":[[[-98.811579,38.698114],[-98.488439,38.698114],[-98.482962,38.522852],[-98.477485,38.259959],[-98.800625,38.259959],[-98.910164,38.259959],[-99.030656,38.34759],[-99.030656,38.698114],[-98.811579,38.698114]]]}}, -{"type":"Feature","id":"20011","properties":{"name":"Bourbon"},"geometry":{"type":"Polygon","coordinates":[[[-94.933905,38.035405],[-94.616242,38.035405],[-94.616242,37.673926],[-94.884612,37.673926],[-95.087259,37.673926],[-95.087259,37.734173],[-95.076305,38.035405],[-94.933905,38.035405]]]}}, -{"type":"Feature","id":"20013","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-95.788308,40.001626],[-95.339199,40.001626],[-95.339199,39.651102],[-95.393968,39.651102],[-95.563753,39.651102],[-95.728061,39.651102],[-95.788308,39.651102],[-95.788308,40.001626]]]}}, -{"type":"Feature","id":"20015","properties":{"name":"Butler"},"geometry":{"type":"Polygon","coordinates":[[[-97.113727,38.084697],[-96.83988,38.084697],[-96.522218,38.084697],[-96.527695,37.608203],[-96.527695,37.476757],[-97.080866,37.476757],[-97.152066,37.476757],[-97.152066,37.914912],[-97.152066,38.090174],[-97.113727,38.084697]]]}}, -{"type":"Feature","id":"20017","properties":{"name":"Chase"},"geometry":{"type":"Polygon","coordinates":[[[-96.817972,38.522852],[-96.352432,38.522852],[-96.357909,38.172328],[-96.522218,38.084697],[-96.83988,38.084697],[-96.817972,38.522852]]]}}, -{"type":"Feature","id":"20019","properties":{"name":"Chautauqua"},"geometry":{"type":"Polygon","coordinates":[[[-96.522218,37.301494],[-95.96357,37.301494],[-95.96357,37.000263],[-96.001908,37.000263],[-96.527695,37.000263],[-96.522218,37.301494]]]}}, -{"type":"Feature","id":"20021","properties":{"name":"Cherokee"},"geometry":{"type":"Polygon","coordinates":[[[-94.829843,37.339833],[-94.616242,37.339833],[-94.616242,37.055032],[-94.616242,37.055032],[-94.616242,37.000263],[-94.994151,37.000263],[-95.005105,37.000263],[-95.070828,37.000263],[-95.076305,37.339833],[-94.829843,37.339833]]]}}, -{"type":"Feature","id":"20023","properties":{"name":"Cheyenne"},"geometry":{"type":"Polygon","coordinates":[[[-101.90605,40.001626],[-101.413125,40.001626],[-101.413125,39.568948],[-102.004635,39.568948],[-102.04845,39.568948],[-102.04845,39.574425],[-102.053927,40.001626],[-101.90605,40.001626]]]}}, -{"type":"Feature","id":"20025","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-100.054844,37.47128],[-99.556443,37.465803],[-99.545489,37.383649],[-99.540012,37.000263],[-100.000075,37.000263],[-100.087706,37.000263],[-100.109614,37.476757],[-100.054844,37.47128]]]}}, -{"type":"Feature","id":"20027","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-97.299943,39.568948],[-96.960373,39.568948],[-96.960373,39.218424],[-96.96585,39.130793],[-97.261605,39.130793],[-97.371143,39.130793],[-97.371143,39.306055],[-97.371143,39.568948],[-97.299943,39.568948]]]}}, -{"type":"Feature","id":"20029","properties":{"name":"Cloud"},"geometry":{"type":"Polygon","coordinates":[[[-97.69976,39.656579],[-97.371143,39.656579],[-97.371143,39.568948],[-97.371143,39.306055],[-97.590221,39.306055],[-97.929791,39.306055],[-97.929791,39.568948],[-97.929791,39.656579],[-97.69976,39.656579]]]}}, -{"type":"Feature","id":"20031","properties":{"name":"Coffey"},"geometry":{"type":"Polygon","coordinates":[[[-95.656861,38.435221],[-95.508984,38.435221],[-95.508984,38.391406],[-95.519938,38.040881],[-95.810215,38.040881],[-95.958093,38.040881],[-95.958093,38.172328],[-95.952616,38.435221],[-95.656861,38.435221]]]}}, -{"type":"Feature","id":"20033","properties":{"name":"Comanche"},"geometry":{"type":"Polygon","coordinates":[[[-99.014225,37.383649],[-99.003272,37.000263],[-99.457858,37.000263],[-99.540012,37.000263],[-99.545489,37.383649],[-99.014225,37.383649]]]}}, -{"type":"Feature","id":"20035","properties":{"name":"Cowley"},"geometry":{"type":"Polygon","coordinates":[[[-97.080866,37.476757],[-96.527695,37.476757],[-96.522218,37.301494],[-96.527695,37.000263],[-96.730341,37.000263],[-96.752249,37.000263],[-96.867265,37.000263],[-97.146589,37.000263],[-97.152066,37.476757],[-97.080866,37.476757]]]}}, -{"type":"Feature","id":"20037","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-94.884612,37.673926],[-94.616242,37.673926],[-94.616242,37.652019],[-94.616242,37.361741],[-94.616242,37.339833],[-94.829843,37.339833],[-95.076305,37.339833],[-95.087259,37.383649],[-95.087259,37.673926],[-94.884612,37.673926]]]}}, -{"type":"Feature","id":"20039","properties":{"name":"Decatur"},"geometry":{"type":"Polygon","coordinates":[[[-100.739462,40.001626],[-100.191768,40.001626],[-100.175337,40.001626],[-100.180814,39.568948],[-100.668261,39.568948],[-100.717554,39.568948],[-100.739462,39.568948],[-100.739462,40.001626]]]}}, -{"type":"Feature","id":"20041","properties":{"name":"Dickinson"},"geometry":{"type":"Polygon","coordinates":[[[-97.261605,39.130793],[-96.96585,39.130793],[-96.889173,38.867899],[-96.932988,38.610483],[-97.261605,38.610483],[-97.371143,38.610483],[-97.371143,38.95553],[-97.371143,39.130793],[-97.261605,39.130793]]]}}, -{"type":"Feature","id":"20043","properties":{"name":"Doniphan"},"geometry":{"type":"Polygon","coordinates":[[[-95.339199,40.001626],[-95.306337,40.001626],[-94.994151,39.897564],[-94.879136,39.820887],[-95.054398,39.623717],[-95.339199,39.651102],[-95.339199,40.001626]]]}}, -{"type":"Feature","id":"20045","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-95.49803,39.054115],[-95.185844,39.043162],[-95.054398,38.982915],[-95.054398,38.736453],[-95.49803,38.736453],[-95.503507,38.736453],[-95.49803,38.867899],[-95.49803,39.054115]]]}}, -{"type":"Feature","id":"20047","properties":{"name":"Edwards"},"geometry":{"type":"Polygon","coordinates":[[[-99.348319,38.002543],[-99.019702,38.002543],[-99.014225,37.827281],[-99.014225,37.734173],[-99.56192,37.734173],[-99.567396,37.914912],[-99.567396,38.084697],[-99.348319,38.002543]]]}}, -{"type":"Feature","id":"20049","properties":{"name":"Elk"},"geometry":{"type":"Polygon","coordinates":[[[-96.308617,37.608203],[-95.96357,37.602726],[-95.96357,37.389126],[-95.96357,37.301494],[-96.522218,37.301494],[-96.527695,37.476757],[-96.527695,37.608203],[-96.308617,37.608203]]]}}, -{"type":"Feature","id":"20051","properties":{"name":"Ellis"},"geometry":{"type":"Polygon","coordinates":[[[-99.408565,39.130793],[-99.047087,39.130793],[-99.036133,39.130793],[-99.04161,38.698114],[-99.583827,38.698114],[-99.600258,38.698114],[-99.589304,39.130793],[-99.408565,39.130793]]]}}, -{"type":"Feature","id":"20053","properties":{"name":"Ellsworth"},"geometry":{"type":"Polygon","coordinates":[[[-97.929791,38.873376],[-97.924314,38.610483],[-97.924314,38.522852],[-98.017422,38.522852],[-98.482962,38.522852],[-98.488439,38.698114],[-98.482962,38.873376],[-97.929791,38.873376]]]}}, -{"type":"Feature","id":"20055","properties":{"name":"Finney"},"geometry":{"type":"Polygon","coordinates":[[[-100.881862,38.265436],[-100.684692,38.265436],[-100.246537,38.259959],[-100.224629,38.259959],[-100.224629,38.002543],[-100.651831,37.734173],[-101.089986,37.734173],[-101.10094,38.265436],[-100.881862,38.265436]]]}}, -{"type":"Feature","id":"20057","properties":{"name":"Ford"},"geometry":{"type":"Polygon","coordinates":[[[-99.874105,37.914912],[-99.567396,37.914912],[-99.56192,37.734173],[-99.556443,37.465803],[-100.054844,37.47128],[-100.109614,37.476757],[-100.213675,37.476757],[-100.224629,37.914912],[-99.874105,37.914912]]]}}, -{"type":"Feature","id":"20059","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-95.49803,38.736453],[-95.054398,38.736453],[-95.065351,38.391406],[-95.235137,38.391406],[-95.508984,38.391406],[-95.508984,38.435221],[-95.503507,38.736453],[-95.49803,38.736453]]]}}, -{"type":"Feature","id":"20061","properties":{"name":"Geary"},"geometry":{"type":"Polygon","coordinates":[[[-96.943942,39.218424],[-96.50031,39.043162],[-96.50031,38.867899],[-96.686526,38.867899],[-96.889173,38.867899],[-96.96585,39.130793],[-96.960373,39.218424],[-96.943942,39.218424]]]}}, -{"type":"Feature","id":"20063","properties":{"name":"Gove"},"geometry":{"type":"Polygon","coordinates":[[[-100.739462,39.130793],[-100.723031,39.130793],[-100.164383,39.130793],[-100.147952,39.130793],[-100.153429,38.698114],[-100.246537,38.698114],[-100.58063,38.698114],[-100.690169,38.698114],[-100.816139,38.698114],[-100.810662,39.130793],[-100.739462,39.130793]]]}}, -{"type":"Feature","id":"20065","properties":{"name":"Graham"},"geometry":{"type":"Polygon","coordinates":[[[-99.600258,39.568948],[-99.605735,39.130793],[-100.147952,39.130793],[-100.164383,39.130793],[-100.164383,39.568948],[-99.627643,39.568948],[-99.600258,39.568948]]]}}, -{"type":"Feature","id":"20067","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-101.17214,37.734173],[-101.089986,37.734173],[-101.089986,37.389126],[-101.528141,37.389126],[-101.528141,37.734173],[-101.17214,37.734173]]]}}, -{"type":"Feature","id":"20069","properties":{"name":"Gray"},"geometry":{"type":"Polygon","coordinates":[[[-100.224629,38.002543],[-100.224629,37.914912],[-100.213675,37.476757],[-100.651831,37.476757],[-100.651831,37.734173],[-100.224629,38.002543]]]}}, -{"type":"Feature","id":"20071","properties":{"name":"Greeley"},"geometry":{"type":"Polygon","coordinates":[[[-101.56648,38.698114],[-101.56648,38.265436],[-102.042974,38.259959],[-102.042974,38.270913],[-102.042974,38.61596],[-102.042974,38.698114],[-101.56648,38.698114]]]}}, -{"type":"Feature","id":"20073","properties":{"name":"Greenwood"},"geometry":{"type":"Polygon","coordinates":[[[-96.281232,38.172328],[-95.958093,38.172328],[-95.958093,38.040881],[-95.96357,37.734173],[-95.96357,37.602726],[-96.308617,37.608203],[-96.527695,37.608203],[-96.522218,38.084697],[-96.357909,38.172328],[-96.281232,38.172328]]]}}, -{"type":"Feature","id":"20075","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-101.56648,38.265436],[-101.544572,38.265436],[-101.528141,37.734173],[-102.042974,37.73965],[-102.042974,38.259959],[-101.56648,38.265436]]]}}, -{"type":"Feature","id":"20077","properties":{"name":"Harper"},"geometry":{"type":"Polygon","coordinates":[[[-97.803822,37.389126],[-97.803822,37.000263],[-98.11053,37.000263],[-98.346039,37.000263],[-98.351516,37.383649],[-97.809299,37.383649],[-97.803822,37.389126]]]}}, -{"type":"Feature","id":"20079","properties":{"name":"Harvey"},"geometry":{"type":"Polygon","coordinates":[[[-97.152066,38.172328],[-97.152066,38.090174],[-97.152066,37.914912],[-97.157543,37.914912],[-97.69976,37.914912],[-97.69976,38.172328],[-97.371143,38.172328],[-97.152066,38.172328]]]}}, -{"type":"Feature","id":"20081","properties":{"name":"Haskell"},"geometry":{"type":"Polygon","coordinates":[[[-100.651831,37.734173],[-100.651831,37.476757],[-100.651831,37.389126],[-100.750416,37.389126],[-101.068078,37.389126],[-101.089986,37.389126],[-101.089986,37.734173],[-100.651831,37.734173]]]}}, -{"type":"Feature","id":"20083","properties":{"name":"Hodgeman"},"geometry":{"type":"Polygon","coordinates":[[[-99.57835,38.259959],[-99.567396,38.084697],[-99.567396,37.914912],[-99.874105,37.914912],[-100.224629,37.914912],[-100.224629,38.002543],[-100.224629,38.259959],[-99.583827,38.259959],[-99.57835,38.259959]]]}}, -{"type":"Feature","id":"20085","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-95.728061,39.651102],[-95.563753,39.651102],[-95.56923,39.42107],[-95.591138,39.218424],[-95.886893,39.218424],[-96.03477,39.218424],[-96.03477,39.563471],[-95.788308,39.651102],[-95.728061,39.651102]]]}}, -{"type":"Feature","id":"20087","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-95.465168,39.42107],[-95.180367,39.42107],[-95.185844,39.043162],[-95.49803,39.054115],[-95.591138,39.218424],[-95.56923,39.42107],[-95.465168,39.42107]]]}}, -{"type":"Feature","id":"20089","properties":{"name":"Jewell"},"geometry":{"type":"Polygon","coordinates":[[[-98.269362,40.001626],[-97.929791,40.001626],[-97.929791,39.656579],[-97.929791,39.568948],[-98.488439,39.568948],[-98.50487,39.568948],[-98.50487,40.001626],[-98.274839,40.001626],[-98.269362,40.001626]]]}}, -{"type":"Feature","id":"20091","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-94.90652,38.988392],[-94.605288,39.043162],[-94.610765,38.845992],[-94.610765,38.736453],[-94.966767,38.736453],[-95.054398,38.736453],[-95.054398,38.982915],[-94.90652,38.988392]]]}}, -{"type":"Feature","id":"20093","properties":{"name":"Kearny"},"geometry":{"type":"Polygon","coordinates":[[[-101.122848,38.265436],[-101.10094,38.265436],[-101.089986,37.734173],[-101.17214,37.734173],[-101.528141,37.734173],[-101.544572,38.265436],[-101.122848,38.265436]]]}}, -{"type":"Feature","id":"20095","properties":{"name":"Kingman"},"geometry":{"type":"Polygon","coordinates":[[[-97.918837,37.734173],[-97.809299,37.734173],[-97.809299,37.476757],[-97.809299,37.383649],[-98.351516,37.383649],[-98.466531,37.47128],[-98.466531,37.734173],[-97.918837,37.734173]]]}}, -{"type":"Feature","id":"20097","properties":{"name":"Kiowa"},"geometry":{"type":"Polygon","coordinates":[[[-99.56192,37.734173],[-99.014225,37.734173],[-99.014225,37.47128],[-99.014225,37.383649],[-99.545489,37.383649],[-99.556443,37.465803],[-99.56192,37.734173]]]}}, -{"type":"Feature","id":"20099","properties":{"name":"Labette"},"geometry":{"type":"Polygon","coordinates":[[[-95.125598,37.383649],[-95.087259,37.383649],[-95.076305,37.339833],[-95.070828,37.000263],[-95.152983,37.000263],[-95.410399,37.000263],[-95.519938,37.000263],[-95.519938,37.383649],[-95.125598,37.383649]]]}}, -{"type":"Feature","id":"20101","properties":{"name":"Lane"},"geometry":{"type":"Polygon","coordinates":[[[-100.58063,38.698114],[-100.246537,38.698114],[-100.246537,38.259959],[-100.684692,38.265436],[-100.690169,38.698114],[-100.58063,38.698114]]]}}, -{"type":"Feature","id":"20103","properties":{"name":"Leavenworth"},"geometry":{"type":"Polygon","coordinates":[[[-95.065351,39.42107],[-94.966767,39.42107],[-94.775074,39.201993],[-94.862705,39.201993],[-94.90652,38.988392],[-95.054398,38.982915],[-95.185844,39.043162],[-95.180367,39.42107],[-95.065351,39.42107]]]}}, -{"type":"Feature","id":"20105","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-98.477485,39.218424],[-97.929791,39.218424],[-97.929791,38.95553],[-97.929791,38.873376],[-98.482962,38.873376],[-98.488439,39.130793],[-98.488439,39.218424],[-98.477485,39.218424]]]}}, -{"type":"Feature","id":"20107","properties":{"name":"Linn"},"geometry":{"type":"Polygon","coordinates":[[[-95.010582,38.391406],[-94.610765,38.391406],[-94.616242,38.062789],[-94.616242,38.035405],[-94.933905,38.035405],[-95.076305,38.035405],[-95.065351,38.391406],[-95.010582,38.391406]]]}}, -{"type":"Feature","id":"20109","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-101.391218,39.13627],[-100.810662,39.130793],[-100.816139,38.698114],[-101.128324,38.698114],[-101.259771,38.703591],[-101.484326,38.698114],[-101.478849,39.13627],[-101.391218,39.13627]]]}}, -{"type":"Feature","id":"20111","properties":{"name":"Lyon"},"geometry":{"type":"Polygon","coordinates":[[[-96.336002,38.74193],[-95.947139,38.736453],[-95.952616,38.435221],[-95.958093,38.172328],[-96.281232,38.172328],[-96.357909,38.172328],[-96.352432,38.522852],[-96.352432,38.74193],[-96.336002,38.74193]]]}}, -{"type":"Feature","id":"20113","properties":{"name":"McPherson"},"geometry":{"type":"Polygon","coordinates":[[[-97.924314,38.610483],[-97.371143,38.610483],[-97.371143,38.172328],[-97.69976,38.172328],[-97.924314,38.172328],[-97.924314,38.522852],[-97.924314,38.610483]]]}}, -{"type":"Feature","id":"20115","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-97.261605,38.610483],[-96.932988,38.610483],[-96.817972,38.522852],[-96.83988,38.084697],[-97.113727,38.084697],[-97.152066,38.090174],[-97.152066,38.172328],[-97.371143,38.172328],[-97.371143,38.610483],[-97.261605,38.610483]]]}}, -{"type":"Feature","id":"20117","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-96.692003,40.001626],[-96.461971,40.001626],[-96.237417,40.001626],[-96.237417,39.568948],[-96.582464,39.568948],[-96.582464,39.568948],[-96.692003,39.568948],[-96.807019,39.568948],[-96.807019,40.001626],[-96.692003,40.001626]]]}}, -{"type":"Feature","id":"20119","properties":{"name":"Meade"},"geometry":{"type":"Polygon","coordinates":[[[-100.213675,37.476757],[-100.109614,37.476757],[-100.087706,37.000263],[-100.6354,37.000263],[-100.651831,37.389126],[-100.651831,37.476757],[-100.213675,37.476757]]]}}, -{"type":"Feature","id":"20121","properties":{"name":"Miami"},"geometry":{"type":"Polygon","coordinates":[[[-94.966767,38.736453],[-94.610765,38.736453],[-94.610765,38.479037],[-94.610765,38.391406],[-95.010582,38.391406],[-95.065351,38.391406],[-95.054398,38.736453],[-94.966767,38.736453]]]}}, -{"type":"Feature","id":"20123","properties":{"name":"Mitchell"},"geometry":{"type":"Polygon","coordinates":[[[-98.488439,39.568948],[-97.929791,39.568948],[-97.929791,39.306055],[-97.929791,39.218424],[-98.477485,39.218424],[-98.488439,39.218424],[-98.488439,39.568948]]]}}, -{"type":"Feature","id":"20125","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-95.96357,37.389126],[-95.525414,37.383649],[-95.519938,37.383649],[-95.519938,37.000263],[-95.613046,37.000263],[-95.788308,37.000263],[-95.9088,37.000263],[-95.96357,37.000263],[-95.96357,37.301494],[-95.96357,37.389126]]]}}, -{"type":"Feature","id":"20127","properties":{"name":"Morris"},"geometry":{"type":"Polygon","coordinates":[[[-96.686526,38.867899],[-96.50031,38.867899],[-96.352432,38.74193],[-96.352432,38.522852],[-96.817972,38.522852],[-96.932988,38.610483],[-96.889173,38.867899],[-96.686526,38.867899]]]}}, -{"type":"Feature","id":"20129","properties":{"name":"Morton"},"geometry":{"type":"Polygon","coordinates":[[[-101.884142,37.389126],[-101.555526,37.389126],[-101.555526,36.994786],[-102.026543,36.994786],[-102.042974,36.994786],[-102.042974,37.389126],[-101.884142,37.389126]]]}}, -{"type":"Feature","id":"20131","properties":{"name":"Nemaha"},"geometry":{"type":"Polygon","coordinates":[[[-96.237417,40.001626],[-96.012862,40.001626],[-95.788308,40.001626],[-95.788308,39.651102],[-96.03477,39.563471],[-96.237417,39.568948],[-96.237417,40.001626],[-96.237417,40.001626]]]}}, -{"type":"Feature","id":"20133","properties":{"name":"Neosho"},"geometry":{"type":"Polygon","coordinates":[[[-95.399445,37.734173],[-95.087259,37.734173],[-95.087259,37.673926],[-95.087259,37.383649],[-95.125598,37.383649],[-95.519938,37.383649],[-95.525414,37.383649],[-95.525414,37.734173],[-95.399445,37.734173]]]}}, -{"type":"Feature","id":"20135","properties":{"name":"Ness"},"geometry":{"type":"Polygon","coordinates":[[[-100.246537,38.698114],[-100.153429,38.698114],[-99.600258,38.698114],[-99.583827,38.698114],[-99.583827,38.34759],[-99.583827,38.259959],[-100.224629,38.259959],[-100.246537,38.259959],[-100.246537,38.698114]]]}}, -{"type":"Feature","id":"20137","properties":{"name":"Norton"},"geometry":{"type":"Polygon","coordinates":[[[-99.627643,40.001626],[-99.627643,39.568948],[-100.164383,39.568948],[-100.180814,39.568948],[-100.175337,40.001626],[-99.627643,40.001626],[-99.627643,40.001626]]]}}, -{"type":"Feature","id":"20139","properties":{"name":"Osage"},"geometry":{"type":"Polygon","coordinates":[[[-95.667815,38.867899],[-95.49803,38.867899],[-95.503507,38.736453],[-95.508984,38.435221],[-95.656861,38.435221],[-95.952616,38.435221],[-95.947139,38.736453],[-95.947139,38.867899],[-95.667815,38.867899]]]}}, -{"type":"Feature","id":"20141","properties":{"name":"Osborne"},"geometry":{"type":"Polygon","coordinates":[[[-98.849917,39.568948],[-98.50487,39.568948],[-98.488439,39.568948],[-98.488439,39.218424],[-98.488439,39.130793],[-98.510347,39.130793],[-99.036133,39.130793],[-99.047087,39.130793],[-99.04161,39.568948],[-98.849917,39.568948]]]}}, -{"type":"Feature","id":"20143","properties":{"name":"Ottawa"},"geometry":{"type":"Polygon","coordinates":[[[-97.590221,39.306055],[-97.371143,39.306055],[-97.371143,39.130793],[-97.371143,38.95553],[-97.486159,38.95553],[-97.929791,38.95553],[-97.929791,39.218424],[-97.929791,39.306055],[-97.590221,39.306055]]]}}, -{"type":"Feature","id":"20145","properties":{"name":"Pawnee"},"geometry":{"type":"Polygon","coordinates":[[[-99.359273,38.34759],[-99.030656,38.34759],[-98.910164,38.259959],[-99.019702,38.002543],[-99.348319,38.002543],[-99.567396,38.084697],[-99.57835,38.259959],[-99.583827,38.259959],[-99.583827,38.34759],[-99.359273,38.34759]]]}}, -{"type":"Feature","id":"20147","properties":{"name":"Phillips"},"geometry":{"type":"Polygon","coordinates":[[[-99.123764,40.001626],[-99.068995,40.001626],[-99.063518,39.568948],[-99.600258,39.568948],[-99.627643,39.568948],[-99.627643,40.001626],[-99.178534,40.001626],[-99.123764,40.001626]]]}}, -{"type":"Feature","id":"20149","properties":{"name":"Pottawatomie"},"geometry":{"type":"Polygon","coordinates":[[[-96.582464,39.568948],[-96.237417,39.568948],[-96.03477,39.563471],[-96.03477,39.218424],[-96.040247,39.125316],[-96.390771,39.174608],[-96.582464,39.568948],[-96.582464,39.568948]]]}}, -{"type":"Feature","id":"20151","properties":{"name":"Pratt"},"geometry":{"type":"Polygon","coordinates":[[[-98.904687,37.827281],[-98.472008,37.827281],[-98.466531,37.734173],[-98.466531,37.47128],[-98.482962,37.47128],[-99.014225,37.47128],[-99.014225,37.734173],[-99.014225,37.827281],[-98.904687,37.827281]]]}}, -{"type":"Feature","id":"20153","properties":{"name":"Rawlins"},"geometry":{"type":"Polygon","coordinates":[[[-101.325494,40.001626],[-100.761369,40.001626],[-100.739462,40.001626],[-100.739462,39.568948],[-101.391218,39.568948],[-101.413125,39.568948],[-101.413125,40.001626],[-101.325494,40.001626]]]}}, -{"type":"Feature","id":"20155","properties":{"name":"Reno"},"geometry":{"type":"Polygon","coordinates":[[[-97.929791,38.172328],[-97.924314,38.172328],[-97.69976,38.172328],[-97.69976,37.914912],[-97.809299,37.734173],[-97.918837,37.734173],[-98.466531,37.734173],[-98.472008,37.827281],[-98.472008,38.172328],[-97.929791,38.172328]]]}}, -{"type":"Feature","id":"20157","properties":{"name":"Republic"},"geometry":{"type":"Polygon","coordinates":[[[-97.875022,40.001626],[-97.820252,40.001626],[-97.371143,40.001626],[-97.371143,39.656579],[-97.69976,39.656579],[-97.929791,39.656579],[-97.929791,40.001626],[-97.875022,40.001626]]]}}, -{"type":"Feature","id":"20159","properties":{"name":"Rice"},"geometry":{"type":"Polygon","coordinates":[[[-98.017422,38.522852],[-97.924314,38.522852],[-97.924314,38.172328],[-97.929791,38.172328],[-98.472008,38.172328],[-98.477485,38.259959],[-98.482962,38.522852],[-98.017422,38.522852]]]}}, -{"type":"Feature","id":"20161","properties":{"name":"Riley"},"geometry":{"type":"Polygon","coordinates":[[[-96.692003,39.568948],[-96.582464,39.568948],[-96.390771,39.174608],[-96.50031,39.043162],[-96.943942,39.218424],[-96.960373,39.218424],[-96.960373,39.568948],[-96.807019,39.568948],[-96.692003,39.568948]]]}}, -{"type":"Feature","id":"20163","properties":{"name":"Rooks"},"geometry":{"type":"Polygon","coordinates":[[[-99.063518,39.568948],[-99.04161,39.568948],[-99.047087,39.130793],[-99.408565,39.130793],[-99.589304,39.130793],[-99.605735,39.130793],[-99.600258,39.568948],[-99.063518,39.568948]]]}}, -{"type":"Feature","id":"20165","properties":{"name":"Rush"},"geometry":{"type":"Polygon","coordinates":[[[-99.04161,38.698114],[-99.030656,38.698114],[-99.030656,38.34759],[-99.359273,38.34759],[-99.583827,38.34759],[-99.583827,38.698114],[-99.04161,38.698114]]]}}, -{"type":"Feature","id":"20167","properties":{"name":"Russell"},"geometry":{"type":"Polygon","coordinates":[[[-98.510347,39.130793],[-98.488439,39.130793],[-98.482962,38.873376],[-98.488439,38.698114],[-98.811579,38.698114],[-99.030656,38.698114],[-99.04161,38.698114],[-99.036133,39.130793],[-98.510347,39.130793]]]}}, -{"type":"Feature","id":"20169","properties":{"name":"Saline"},"geometry":{"type":"Polygon","coordinates":[[[-97.486159,38.95553],[-97.371143,38.95553],[-97.371143,38.610483],[-97.924314,38.610483],[-97.929791,38.873376],[-97.929791,38.95553],[-97.486159,38.95553]]]}}, -{"type":"Feature","id":"20171","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-101.128324,38.698114],[-100.816139,38.698114],[-100.690169,38.698114],[-100.684692,38.265436],[-100.881862,38.265436],[-101.10094,38.265436],[-101.122848,38.265436],[-101.128324,38.698114]]]}}, -{"type":"Feature","id":"20173","properties":{"name":"Sedgwick"},"geometry":{"type":"Polygon","coordinates":[[[-97.157543,37.914912],[-97.152066,37.914912],[-97.152066,37.476757],[-97.349236,37.476757],[-97.809299,37.476757],[-97.809299,37.734173],[-97.69976,37.914912],[-97.157543,37.914912]]]}}, -{"type":"Feature","id":"20175","properties":{"name":"Seward"},"geometry":{"type":"Polygon","coordinates":[[[-100.750416,37.389126],[-100.651831,37.389126],[-100.6354,37.000263],[-100.947585,37.000263],[-101.068078,37.000263],[-101.068078,37.389126],[-100.750416,37.389126]]]}}, -{"type":"Feature","id":"20177","properties":{"name":"Shawnee"},"geometry":{"type":"Polygon","coordinates":[[[-95.886893,39.218424],[-95.591138,39.218424],[-95.49803,39.054115],[-95.49803,38.867899],[-95.667815,38.867899],[-95.947139,38.867899],[-96.040247,39.125316],[-96.03477,39.218424],[-95.886893,39.218424]]]}}, -{"type":"Feature","id":"20179","properties":{"name":"Sheridan"},"geometry":{"type":"Polygon","coordinates":[[[-100.668261,39.568948],[-100.180814,39.568948],[-100.164383,39.568948],[-100.164383,39.130793],[-100.723031,39.130793],[-100.717554,39.568948],[-100.668261,39.568948]]]}}, -{"type":"Feature","id":"20181","properties":{"name":"Sherman"},"geometry":{"type":"Polygon","coordinates":[[[-102.004635,39.568948],[-101.413125,39.568948],[-101.391218,39.568948],[-101.391218,39.13627],[-101.478849,39.13627],[-102.04845,39.130793],[-102.04845,39.568948],[-102.004635,39.568948]]]}}, -{"type":"Feature","id":"20183","properties":{"name":"Smith"},"geometry":{"type":"Polygon","coordinates":[[[-98.691086,40.001626],[-98.50487,40.001626],[-98.50487,39.568948],[-98.849917,39.568948],[-99.04161,39.568948],[-99.063518,39.568948],[-99.068995,40.001626],[-98.723948,40.001626],[-98.691086,40.001626]]]}}, -{"type":"Feature","id":"20185","properties":{"name":"Stafford"},"geometry":{"type":"Polygon","coordinates":[[[-98.800625,38.259959],[-98.477485,38.259959],[-98.472008,38.172328],[-98.472008,37.827281],[-98.904687,37.827281],[-99.014225,37.827281],[-99.019702,38.002543],[-98.910164,38.259959],[-98.800625,38.259959]]]}}, -{"type":"Feature","id":"20187","properties":{"name":"Stanton"},"geometry":{"type":"Polygon","coordinates":[[[-102.042974,37.73965],[-101.528141,37.734173],[-101.528141,37.389126],[-101.555526,37.389126],[-101.884142,37.389126],[-102.042974,37.389126],[-102.042974,37.646542],[-102.042974,37.73965]]]}}, -{"type":"Feature","id":"20189","properties":{"name":"Stevens"},"geometry":{"type":"Polygon","coordinates":[[[-101.528141,37.389126],[-101.089986,37.389126],[-101.068078,37.389126],[-101.068078,37.000263],[-101.555526,36.994786],[-101.555526,37.389126],[-101.528141,37.389126]]]}}, -{"type":"Feature","id":"20191","properties":{"name":"Sumner"},"geometry":{"type":"Polygon","coordinates":[[[-97.349236,37.476757],[-97.152066,37.476757],[-97.146589,37.000263],[-97.464251,37.000263],[-97.650467,37.000263],[-97.803822,37.000263],[-97.803822,37.389126],[-97.809299,37.383649],[-97.809299,37.476757],[-97.349236,37.476757]]]}}, -{"type":"Feature","id":"20193","properties":{"name":"Thomas"},"geometry":{"type":"Polygon","coordinates":[[[-101.391218,39.568948],[-100.739462,39.568948],[-100.717554,39.568948],[-100.723031,39.130793],[-100.739462,39.130793],[-100.810662,39.130793],[-101.391218,39.13627],[-101.391218,39.568948]]]}}, -{"type":"Feature","id":"20195","properties":{"name":"Trego"},"geometry":{"type":"Polygon","coordinates":[[[-99.589304,39.130793],[-99.600258,38.698114],[-100.153429,38.698114],[-100.147952,39.130793],[-99.605735,39.130793],[-99.589304,39.130793]]]}}, -{"type":"Feature","id":"20197","properties":{"name":"Wabaunsee"},"geometry":{"type":"Polygon","coordinates":[[[-96.040247,39.125316],[-95.947139,38.867899],[-95.947139,38.736453],[-96.336002,38.74193],[-96.352432,38.74193],[-96.50031,38.867899],[-96.50031,39.043162],[-96.390771,39.174608],[-96.040247,39.125316]]]}}, -{"type":"Feature","id":"20199","properties":{"name":"Wallace"},"geometry":{"type":"Polygon","coordinates":[[[-101.478849,39.13627],[-101.484326,38.698114],[-101.56648,38.698114],[-102.042974,38.698114],[-102.04845,39.048638],[-102.04845,39.130793],[-101.478849,39.13627]]]}}, -{"type":"Feature","id":"20201","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-97.349236,40.001626],[-96.916557,40.001626],[-96.807019,40.001626],[-96.807019,39.568948],[-96.960373,39.568948],[-97.299943,39.568948],[-97.371143,39.568948],[-97.371143,39.656579],[-97.371143,40.001626],[-97.349236,40.001626]]]}}, -{"type":"Feature","id":"20203","properties":{"name":"Wichita"},"geometry":{"type":"Polygon","coordinates":[[[-101.259771,38.703591],[-101.128324,38.698114],[-101.122848,38.265436],[-101.544572,38.265436],[-101.56648,38.265436],[-101.56648,38.698114],[-101.484326,38.698114],[-101.259771,38.703591]]]}}, -{"type":"Feature","id":"20205","properties":{"name":"Wilson"},"geometry":{"type":"Polygon","coordinates":[[[-95.919754,37.734173],[-95.525414,37.734173],[-95.525414,37.383649],[-95.96357,37.389126],[-95.96357,37.602726],[-95.96357,37.734173],[-95.919754,37.734173]]]}}, -{"type":"Feature","id":"20207","properties":{"name":"Woodson"},"geometry":{"type":"Polygon","coordinates":[[[-95.810215,38.040881],[-95.519938,38.040881],[-95.525414,37.734173],[-95.919754,37.734173],[-95.96357,37.734173],[-95.958093,38.040881],[-95.810215,38.040881]]]}}, -{"type":"Feature","id":"20209","properties":{"name":"Wyandotte"},"geometry":{"type":"Polygon","coordinates":[[[-94.862705,39.201993],[-94.775074,39.201993],[-94.599812,39.158177],[-94.605288,39.114362],[-94.605288,39.043162],[-94.90652,38.988392],[-94.862705,39.201993]]]}}, -{"type":"Feature","id":"21001","properties":{"name":"Adair"},"geometry":{"type":"Polygon","coordinates":[[[-85.163043,37.312448],[-85.042551,37.186479],[-85.234244,36.923586],[-85.447844,36.940016],[-85.453321,36.940016],[-85.524521,37.109802],[-85.354736,37.191956],[-85.163043,37.312448]]]}}, -{"type":"Feature","id":"21003","properties":{"name":"Allen"},"geometry":{"type":"Polygon","coordinates":[[[-86.22557,36.912632],[-86.165323,36.934539],[-85.979107,36.720939],[-85.979107,36.627831],[-86.203662,36.638785],[-86.411786,36.649739],[-86.406309,36.775708],[-86.22557,36.912632]]]}}, -{"type":"Feature","id":"21005","properties":{"name":"Anderson"},"geometry":{"type":"Polygon","coordinates":[[[-84.998735,38.128512],[-84.867289,38.117559],[-84.796088,37.969681],[-85.031597,37.893004],[-85.152089,37.898481],[-85.16852,37.969681],[-85.102797,38.035405],[-85.02612,38.128512],[-84.998735,38.128512]]]}}, -{"type":"Feature","id":"21007","properties":{"name":"Ballard"},"geometry":{"type":"Polygon","coordinates":[[[-88.936655,37.230294],[-88.816163,36.956447],[-89.100963,36.945493],[-89.133825,36.983832],[-89.172164,37.065986],[-88.936655,37.230294]]]}}, -{"type":"Feature","id":"21009","properties":{"name":"Barren"},"geometry":{"type":"Polygon","coordinates":[[[-85.743599,37.170048],[-85.738122,36.841432],[-85.979107,36.720939],[-86.165323,36.934539],[-86.116031,37.060509],[-86.055785,37.164571],[-85.743599,37.170048]]]}}, -{"type":"Feature","id":"21011","properties":{"name":"Bath"},"geometry":{"type":"Polygon","coordinates":[[[-83.848578,38.298298],[-83.634977,38.188759],[-83.498053,38.051835],[-83.760947,37.997066],[-83.980024,38.194236],[-83.848578,38.298298]]]}}, -{"type":"Feature","id":"21013","properties":{"name":"Bell"},"geometry":{"type":"Polygon","coordinates":[[[-83.509007,36.940016],[-83.492576,36.896201],[-83.459715,36.666169],[-83.673316,36.600446],[-83.930732,36.589492],[-83.875962,36.688077],[-83.591161,36.956447],[-83.509007,36.940016]]]}}, -{"type":"Feature","id":"21015","properties":{"name":"Boone"},"geometry":{"type":"Polygon","coordinates":[[[-84.620826,39.076023],[-84.615349,38.802176],[-84.659165,38.774791],[-84.779657,38.856946],[-84.796088,38.856946],[-84.872765,38.900761],[-84.878242,39.032208],[-84.817996,39.103408],[-84.620826,39.076023]]]}}, -{"type":"Feature","id":"21017","properties":{"name":"Bourbon"},"geometry":{"type":"Polygon","coordinates":[[[-84.264825,38.325682],[-84.193625,38.369498],[-83.980024,38.194236],[-84.040271,38.144943],[-84.078609,38.117559],[-84.286733,38.068266],[-84.401749,38.20519],[-84.440087,38.281867],[-84.264825,38.325682]]]}}, -{"type":"Feature","id":"21019","properties":{"name":"Boyd"},"geometry":{"type":"Polygon","coordinates":[[[-82.594358,38.424267],[-82.605312,38.249005],[-82.791528,38.243528],[-82.818913,38.374975],[-82.665558,38.506421],[-82.594358,38.424267]]]}}, -{"type":"Feature","id":"21021","properties":{"name":"Boyle"},"geometry":{"type":"Polygon","coordinates":[[[-84.856335,37.695834],[-84.746796,37.712265],[-84.659165,37.635588],[-84.845381,37.547957],[-85.037074,37.54248],[-85.031597,37.630111],[-85.02612,37.679403],[-84.856335,37.695834]]]}}, -{"type":"Feature","id":"21023","properties":{"name":"Bracken"},"geometry":{"type":"Polygon","coordinates":[[[-84.051224,38.769315],[-83.903347,38.769315],[-83.990978,38.594052],[-84.160763,38.555714],[-84.204579,38.583099],[-84.231963,38.829561],[-84.051224,38.769315]]]}}, -{"type":"Feature","id":"21025","properties":{"name":"Breathitt"},"geometry":{"type":"Polygon","coordinates":[[[-83.377561,37.695834],[-83.246114,37.668449],[-82.950359,37.504141],[-83.125621,37.405556],[-83.547346,37.334356],[-83.580208,37.504141],[-83.519961,37.641065],[-83.377561,37.695834]]]}}, -{"type":"Feature","id":"21027","properties":{"name":"Breckinridge"},"geometry":{"type":"Polygon","coordinates":[[[-86.652771,37.843712],[-86.488463,38.046358],[-86.148893,37.799896],[-86.274862,37.591772],[-86.472032,37.602726],[-86.592525,37.564388],[-86.63634,37.662973],[-86.652771,37.843712]]]}}, -{"type":"Feature","id":"21029","properties":{"name":"Bullitt"},"geometry":{"type":"Polygon","coordinates":[[[-85.699783,38.084697],[-85.431413,38.117559],[-85.49166,37.991589],[-85.497137,37.986112],[-85.738122,37.81085],[-85.940769,37.997066],[-85.699783,38.084697]]]}}, -{"type":"Feature","id":"21031","properties":{"name":"Butler"},"geometry":{"type":"Polygon","coordinates":[[[-86.614433,37.394602],[-86.466555,37.323402],[-86.400832,37.170048],[-86.674679,37.000263],[-86.943049,37.071463],[-86.899233,37.213863],[-86.614433,37.394602]]]}}, -{"type":"Feature","id":"21033","properties":{"name":"Caldwell"},"geometry":{"type":"Polygon","coordinates":[[[-87.802929,37.378172],[-87.813882,37.350787],[-87.682436,37.14814],[-87.731728,37.000263],[-87.879606,36.961924],[-88.098683,37.181002],[-87.802929,37.378172]]]}}, -{"type":"Feature","id":"21035","properties":{"name":"Calloway"},"geometry":{"type":"Polygon","coordinates":[[[-88.109637,36.748324],[-88.071299,36.677123],[-88.054868,36.496384],[-88.487546,36.501861],[-88.487546,36.748324],[-88.109637,36.748324]]]}}, -{"type":"Feature","id":"21037","properties":{"name":"Campbell"},"geometry":{"type":"Polygon","coordinates":[[[-84.319594,39.021254],[-84.231963,38.873376],[-84.418179,38.807653],[-84.50581,39.092454],[-84.319594,39.021254]]]}}, -{"type":"Feature","id":"21039","properties":{"name":"Carlisle"},"geometry":{"type":"Polygon","coordinates":[[[-88.810686,36.945493],[-88.810686,36.775708],[-89.122871,36.786662],[-89.100963,36.945493],[-88.816163,36.956447],[-88.810686,36.945493]]]}}, -{"type":"Feature","id":"21041","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-85.02612,38.763838],[-84.933012,38.659776],[-85.075412,38.599529],[-85.16852,38.583099],[-85.332828,38.736453],[-85.201382,38.692637],[-85.02612,38.763838]]]}}, -{"type":"Feature","id":"21043","properties":{"name":"Carter"},"geometry":{"type":"Polygon","coordinates":[[[-83.16396,38.506421],[-82.818913,38.374975],[-82.791528,38.243528],[-82.922975,38.177805],[-83.246114,38.194236],[-83.339222,38.320205],[-83.16396,38.506421]]]}}, -{"type":"Feature","id":"21045","properties":{"name":"Casey"},"geometry":{"type":"Polygon","coordinates":[[[-85.037074,37.54248],[-84.845381,37.547957],[-84.719411,37.235771],[-84.90015,37.115279],[-85.042551,37.186479],[-85.163043,37.312448],[-85.075412,37.411033],[-85.037074,37.54248]]]}}, -{"type":"Feature","id":"21047","properties":{"name":"Christian"},"geometry":{"type":"Polygon","coordinates":[[[-87.682436,37.14814],[-87.331912,37.159094],[-87.260711,37.071463],[-87.260711,37.071463],[-87.337389,36.644262],[-87.63862,36.638785],[-87.69339,36.638785],[-87.731728,37.000263],[-87.682436,37.14814]]]}}, -{"type":"Feature","id":"21049","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-84.078609,38.117559],[-83.96907,37.931343],[-83.990978,37.914912],[-84.001932,37.838235],[-84.078609,37.854665],[-84.270302,37.914912],[-84.336025,37.893004],[-84.286733,38.068266],[-84.078609,38.117559]]]}}, -{"type":"Feature","id":"21051","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-83.574731,37.279587],[-83.525438,37.257679],[-83.509007,37.235771],[-83.509007,36.940016],[-83.591161,36.956447],[-83.788331,37.033124],[-83.870485,37.055032],[-83.941686,37.252202],[-83.782854,37.350787],[-83.574731,37.279587]]]}}, -{"type":"Feature","id":"21053","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-85.217813,36.852385],[-85.064458,36.857862],[-84.976827,36.616877],[-85.278059,36.627831],[-85.29449,36.627831],[-85.217813,36.852385]]]}}, -{"type":"Feature","id":"21055","properties":{"name":"Crittenden"},"geometry":{"type":"Polygon","coordinates":[[[-88.060345,37.504141],[-87.934375,37.482234],[-87.802929,37.378172],[-88.098683,37.181002],[-88.191791,37.14814],[-88.3561,37.405556],[-88.060345,37.504141]]]}}, -{"type":"Feature","id":"21057","properties":{"name":"Cumberland"},"geometry":{"type":"Polygon","coordinates":[[[-85.447844,36.940016],[-85.234244,36.923586],[-85.217813,36.852385],[-85.29449,36.627831],[-85.43689,36.616877],[-85.595722,36.819524],[-85.453321,36.940016],[-85.447844,36.940016]]]}}, -{"type":"Feature","id":"21059","properties":{"name":"Daviess"},"geometry":{"type":"Polygon","coordinates":[[[-87.266188,37.876573],[-86.981388,37.931343],[-86.822556,37.73965],[-87.036157,37.558911],[-87.408589,37.68488],[-87.304527,37.898481],[-87.266188,37.876573]]]}}, -{"type":"Feature","id":"21061","properties":{"name":"Edmonson"},"geometry":{"type":"Polygon","coordinates":[[[-86.466555,37.323402],[-86.159846,37.334356],[-86.055785,37.164571],[-86.116031,37.060509],[-86.400832,37.170048],[-86.466555,37.323402]]]}}, -{"type":"Feature","id":"21063","properties":{"name":"Elliott"},"geometry":{"type":"Polygon","coordinates":[[[-82.922975,38.177805],[-83.02156,38.00802],[-83.262545,38.117559],[-83.246114,38.194236],[-82.922975,38.177805]]]}}, -{"type":"Feature","id":"21065","properties":{"name":"Estill"},"geometry":{"type":"Polygon","coordinates":[[[-84.078609,37.854665],[-84.001932,37.838235],[-83.722608,37.717742],[-83.903347,37.54248],[-83.963593,37.580818],[-84.089563,37.564388],[-84.078609,37.854665]]]}}, -{"type":"Feature","id":"21067","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-84.401749,38.20519],[-84.286733,38.068266],[-84.336025,37.893004],[-84.43461,37.849189],[-84.659165,38.002543],[-84.626303,38.117559],[-84.401749,38.20519]]]}}, -{"type":"Feature","id":"21069","properties":{"name":"Fleming"},"geometry":{"type":"Polygon","coordinates":[[[-83.602115,38.506421],[-83.454238,38.380452],[-83.634977,38.188759],[-83.848578,38.298298],[-83.980024,38.440698],[-83.930732,38.489991],[-83.640454,38.522852],[-83.602115,38.506421]]]}}, -{"type":"Feature","id":"21071","properties":{"name":"Floyd"},"geometry":{"type":"Polygon","coordinates":[[[-82.786051,37.745127],[-82.638174,37.717742],[-82.561497,37.68488],[-82.709374,37.285064],[-82.922975,37.48771],[-82.939406,37.717742],[-82.786051,37.745127]]]}}, -{"type":"Feature","id":"21073","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-84.861812,38.358544],[-84.741319,38.353067],[-84.724888,38.194236],[-84.867289,38.117559],[-84.998735,38.128512],[-85.02612,38.128512],[-84.998735,38.336636],[-84.872765,38.358544],[-84.861812,38.358544]]]}}, -{"type":"Feature","id":"21075","properties":{"name":"Fulton"},"geometry":{"type":"Polygon","coordinates":[[[-89.095486,36.622354],[-88.832593,36.501861],[-89.117394,36.501861],[-89.347426,36.501861],[-89.418626,36.496384],[-89.325518,36.633308],[-89.172164,36.649739],[-89.095486,36.622354]]]}}, -{"type":"Feature","id":"21077","properties":{"name":"Gallatin"},"geometry":{"type":"Polygon","coordinates":[[[-84.779657,38.856946],[-84.659165,38.774791],[-84.785134,38.720022],[-84.817996,38.709068],[-84.933012,38.659776],[-85.02612,38.763838],[-84.796088,38.856946],[-84.779657,38.856946]]]}}, -{"type":"Feature","id":"21079","properties":{"name":"Garrard"},"geometry":{"type":"Polygon","coordinates":[[[-84.648211,37.81085],[-84.527718,37.767034],[-84.346979,37.537003],[-84.445564,37.48771],[-84.659165,37.635588],[-84.746796,37.712265],[-84.713934,37.816327],[-84.648211,37.81085]]]}}, -{"type":"Feature","id":"21081","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-84.615349,38.802176],[-84.533195,38.791222],[-84.478426,38.54476],[-84.555103,38.495467],[-84.582488,38.47356],[-84.785134,38.720022],[-84.659165,38.774791],[-84.615349,38.802176]]]}}, -{"type":"Feature","id":"21083","properties":{"name":"Graves"},"geometry":{"type":"Polygon","coordinates":[[[-88.723055,36.945493],[-88.482069,36.940016],[-88.487546,36.748324],[-88.487546,36.501861],[-88.514931,36.501861],[-88.816163,36.501861],[-88.810686,36.775708],[-88.810686,36.945493],[-88.723055,36.945493]]]}}, -{"type":"Feature","id":"21085","properties":{"name":"Grayson"},"geometry":{"type":"Polygon","coordinates":[[[-86.472032,37.602726],[-86.274862,37.591772],[-86.044831,37.449372],[-86.159846,37.334356],[-86.466555,37.323402],[-86.614433,37.394602],[-86.592525,37.564388],[-86.472032,37.602726]]]}}, -{"type":"Feature","id":"21087","properties":{"name":"Green"},"geometry":{"type":"Polygon","coordinates":[[[-85.590245,37.47128],[-85.584768,37.47128],[-85.354736,37.191956],[-85.524521,37.109802],[-85.68883,37.181002],[-85.655968,37.421987],[-85.590245,37.47128]]]}}, -{"type":"Feature","id":"21089","properties":{"name":"Greenup"},"geometry":{"type":"Polygon","coordinates":[[[-82.813436,38.572145],[-82.665558,38.506421],[-82.818913,38.374975],[-83.16396,38.506421],[-83.032514,38.725499],[-82.813436,38.572145]]]}}, -{"type":"Feature","id":"21091","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-86.811602,37.997066],[-86.652771,37.843712],[-86.63634,37.662973],[-86.822556,37.73965],[-86.981388,37.931343],[-86.811602,37.997066]]]}}, -{"type":"Feature","id":"21093","properties":{"name":"Hardin"},"geometry":{"type":"Polygon","coordinates":[[[-85.946246,38.00802],[-85.940769,37.997066],[-85.738122,37.81085],[-85.677876,37.734173],[-85.891476,37.438418],[-86.017446,37.449372],[-86.044831,37.449372],[-86.274862,37.591772],[-86.148893,37.799896],[-86.001015,37.997066],[-85.946246,38.00802]]]}}, -{"type":"Feature","id":"21095","properties":{"name":"Harlan"},"geometry":{"type":"Polygon","coordinates":[[[-82.912021,37.000263],[-82.868205,36.972878],[-82.879159,36.890724],[-83.459715,36.666169],[-83.492576,36.896201],[-83.180391,37.022171],[-83.120145,37.000263],[-82.912021,37.000263]]]}}, -{"type":"Feature","id":"21097","properties":{"name":"Harrison"},"geometry":{"type":"Polygon","coordinates":[[[-84.401749,38.561191],[-84.204579,38.583099],[-84.160763,38.555714],[-84.100517,38.457129],[-84.193625,38.369498],[-84.264825,38.325682],[-84.440087,38.281867],[-84.555103,38.495467],[-84.478426,38.54476],[-84.401749,38.561191]]]}}, -{"type":"Feature","id":"21099","properties":{"name":"Hart"},"geometry":{"type":"Polygon","coordinates":[[[-86.017446,37.449372],[-85.891476,37.438418],[-85.655968,37.421987],[-85.68883,37.181002],[-85.743599,37.170048],[-86.055785,37.164571],[-86.159846,37.334356],[-86.044831,37.449372],[-86.017446,37.449372]]]}}, -{"type":"Feature","id":"21101","properties":{"name":"Henderson"},"geometry":{"type":"Polygon","coordinates":[[[-87.698867,37.898481],[-87.452404,37.942297],[-87.304527,37.898481],[-87.408589,37.68488],[-87.49622,37.646542],[-87.731728,37.635588],[-87.928898,37.903958],[-87.698867,37.898481]]]}}, -{"type":"Feature","id":"21103","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-85.16852,38.583099],[-85.075412,38.599529],[-84.872765,38.358544],[-84.998735,38.336636],[-85.283536,38.358544],[-85.316398,38.489991],[-85.16852,38.583099]]]}}, -{"type":"Feature","id":"21105","properties":{"name":"Hickman"},"geometry":{"type":"Polygon","coordinates":[[[-89.122871,36.786662],[-88.810686,36.775708],[-88.816163,36.501861],[-88.827116,36.501861],[-88.832593,36.501861],[-89.095486,36.622354],[-89.172164,36.649739],[-89.122871,36.786662]]]}}, -{"type":"Feature","id":"21107","properties":{"name":"Hopkins"},"geometry":{"type":"Polygon","coordinates":[[[-87.375727,37.569865],[-87.293573,37.389126],[-87.331912,37.159094],[-87.682436,37.14814],[-87.813882,37.350787],[-87.375727,37.569865]]]}}, -{"type":"Feature","id":"21109","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-83.963593,37.580818],[-83.903347,37.54248],[-83.886916,37.520572],[-83.782854,37.350787],[-83.941686,37.252202],[-84.138855,37.317925],[-84.199102,37.520572],[-84.089563,37.564388],[-83.963593,37.580818]]]}}, -{"type":"Feature","id":"21111","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-85.639537,38.380452],[-85.469752,38.287344],[-85.425936,38.144943],[-85.431413,38.117559],[-85.699783,38.084697],[-85.940769,37.997066],[-85.946246,38.00802],[-85.90243,38.177805],[-85.792891,38.287344],[-85.639537,38.380452]]]}}, -{"type":"Feature","id":"21113","properties":{"name":"Jessamine"},"geometry":{"type":"Polygon","coordinates":[[[-84.659165,38.002543],[-84.43461,37.849189],[-84.527718,37.767034],[-84.648211,37.81085],[-84.713934,37.816327],[-84.708457,37.860142],[-84.659165,38.002543]]]}}, -{"type":"Feature","id":"21115","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-82.851774,37.975158],[-82.610789,37.876573],[-82.638174,37.717742],[-82.786051,37.745127],[-82.939406,37.717742],[-83.005129,37.860142],[-82.988698,37.964204],[-82.851774,37.975158]]]}}, -{"type":"Feature","id":"21117","properties":{"name":"Kenton"},"geometry":{"type":"Polygon","coordinates":[[[-84.50581,39.092454],[-84.418179,38.807653],[-84.533195,38.791222],[-84.615349,38.802176],[-84.620826,39.076023],[-84.50581,39.092454]]]}}, -{"type":"Feature","id":"21119","properties":{"name":"Knott"},"geometry":{"type":"Polygon","coordinates":[[[-82.944882,37.498664],[-82.922975,37.48771],[-82.709374,37.285064],[-82.731282,37.27411],[-82.999652,37.197433],[-83.125621,37.405556],[-82.950359,37.504141],[-82.944882,37.498664]]]}}, -{"type":"Feature","id":"21121","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-83.788331,37.033124],[-83.591161,36.956447],[-83.875962,36.688077],[-84.089563,36.956447],[-83.870485,37.055032],[-83.788331,37.033124]]]}}, -{"type":"Feature","id":"21123","properties":{"name":"Larue"},"geometry":{"type":"Polygon","coordinates":[[[-85.677876,37.734173],[-85.519044,37.553434],[-85.464275,37.465803],[-85.584768,37.47128],[-85.590245,37.47128],[-85.655968,37.421987],[-85.891476,37.438418],[-85.677876,37.734173]]]}}, -{"type":"Feature","id":"21125","properties":{"name":"Laurel"},"geometry":{"type":"Polygon","coordinates":[[[-84.138855,37.306971],[-84.138855,37.317925],[-83.941686,37.252202],[-83.870485,37.055032],[-84.089563,36.956447],[-84.122425,36.967401],[-84.297687,36.945493],[-84.357933,36.961924],[-84.286733,37.153617],[-84.138855,37.306971]]]}}, -{"type":"Feature","id":"21127","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-82.791528,38.243528],[-82.605312,38.249005],[-82.495773,37.947773],[-82.610789,37.876573],[-82.851774,37.975158],[-82.988698,37.964204],[-83.02156,38.00802],[-82.922975,38.177805],[-82.791528,38.243528]]]}}, -{"type":"Feature","id":"21129","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-83.706177,37.717742],[-83.519961,37.641065],[-83.580208,37.504141],[-83.651408,37.537003],[-83.886916,37.520572],[-83.903347,37.54248],[-83.722608,37.717742],[-83.706177,37.717742]]]}}, -{"type":"Feature","id":"21131","properties":{"name":"Leslie"},"geometry":{"type":"Polygon","coordinates":[[[-83.509007,37.235771],[-83.180391,37.022171],[-83.492576,36.896201],[-83.509007,36.940016],[-83.509007,37.235771]]]}}, -{"type":"Feature","id":"21133","properties":{"name":"Letcher"},"geometry":{"type":"Polygon","coordinates":[[[-82.731282,37.27411],[-82.566974,37.197433],[-82.868205,36.972878],[-82.912021,37.000263],[-83.120145,37.000263],[-82.999652,37.197433],[-82.731282,37.27411]]]}}, -{"type":"Feature","id":"21135","properties":{"name":"Lewis"},"geometry":{"type":"Polygon","coordinates":[[[-83.268022,38.61596],[-83.032514,38.725499],[-83.16396,38.506421],[-83.339222,38.320205],[-83.410422,38.396883],[-83.454238,38.380452],[-83.602115,38.506421],[-83.640454,38.522852],[-83.645931,38.637868],[-83.268022,38.61596]]]}}, -{"type":"Feature","id":"21137","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-84.659165,37.635588],[-84.445564,37.48771],[-84.500334,37.328879],[-84.670119,37.27411],[-84.719411,37.235771],[-84.845381,37.547957],[-84.659165,37.635588]]]}}, -{"type":"Feature","id":"21139","properties":{"name":"Livingston"},"geometry":{"type":"Polygon","coordinates":[[[-88.361576,37.405556],[-88.3561,37.405556],[-88.191791,37.14814],[-88.241084,36.983832],[-88.432777,37.049555],[-88.482069,37.022171],[-88.564223,37.082417],[-88.487546,37.065986],[-88.416346,37.421987],[-88.361576,37.405556]]]}}, -{"type":"Feature","id":"21141","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-86.954003,37.071463],[-86.943049,37.071463],[-86.674679,37.000263],[-86.608956,36.885247],[-86.76231,36.649739],[-87.058065,36.644262],[-87.052588,37.060509],[-86.954003,37.071463]]]}}, -{"type":"Feature","id":"21143","properties":{"name":"Lyon"},"geometry":{"type":"Polygon","coordinates":[[[-88.191791,37.14814],[-88.098683,37.181002],[-87.879606,36.961924],[-88.15893,36.868816],[-88.241084,36.983832],[-88.191791,37.14814]]]}}, -{"type":"Feature","id":"21145","properties":{"name":"McCracken"},"geometry":{"type":"Polygon","coordinates":[[[-88.925701,37.224817],[-88.564223,37.082417],[-88.482069,37.022171],[-88.482069,36.940016],[-88.723055,36.945493],[-88.810686,36.945493],[-88.816163,36.956447],[-88.936655,37.230294],[-88.925701,37.224817]]]}}, -{"type":"Feature","id":"21147","properties":{"name":"McCreary"},"geometry":{"type":"Polygon","coordinates":[[[-84.357933,36.961924],[-84.297687,36.945493],[-84.226487,36.589492],[-84.259348,36.589492],[-84.779657,36.605923],[-84.577011,36.868816],[-84.357933,36.961924]]]}}, -{"type":"Feature","id":"21149","properties":{"name":"McLean"},"geometry":{"type":"Polygon","coordinates":[[[-87.408589,37.68488],[-87.036157,37.558911],[-87.10188,37.41651],[-87.293573,37.389126],[-87.375727,37.569865],[-87.49622,37.646542],[-87.408589,37.68488]]]}}, -{"type":"Feature","id":"21151","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-84.270302,37.914912],[-84.078609,37.854665],[-84.089563,37.564388],[-84.199102,37.520572],[-84.231963,37.520572],[-84.346979,37.537003],[-84.527718,37.767034],[-84.43461,37.849189],[-84.336025,37.893004],[-84.270302,37.914912]]]}}, -{"type":"Feature","id":"21153","properties":{"name":"Magoffin"},"geometry":{"type":"Polygon","coordinates":[[[-83.005129,37.860142],[-82.939406,37.717742],[-82.922975,37.48771],[-82.944882,37.498664],[-82.950359,37.504141],[-83.246114,37.668449],[-83.262545,37.712265],[-83.005129,37.860142]]]}}, -{"type":"Feature","id":"21155","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-85.404029,37.728696],[-85.031597,37.630111],[-85.037074,37.54248],[-85.075412,37.411033],[-85.464275,37.465803],[-85.519044,37.553434],[-85.404029,37.728696]]]}}, -{"type":"Feature","id":"21157","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-88.432777,37.049555],[-88.241084,36.983832],[-88.15893,36.868816],[-88.109637,36.748324],[-88.487546,36.748324],[-88.482069,36.940016],[-88.482069,37.022171],[-88.432777,37.049555]]]}}, -{"type":"Feature","id":"21159","properties":{"name":"Martin"},"geometry":{"type":"Polygon","coordinates":[[[-82.413619,37.854665],[-82.331465,37.73965],[-82.561497,37.68488],[-82.638174,37.717742],[-82.610789,37.876573],[-82.495773,37.947773],[-82.413619,37.854665]]]}}, -{"type":"Feature","id":"21161","properties":{"name":"Mason"},"geometry":{"type":"Polygon","coordinates":[[[-83.848578,38.747407],[-83.706177,38.637868],[-83.645931,38.637868],[-83.640454,38.522852],[-83.930732,38.489991],[-83.96907,38.583099],[-83.990978,38.594052],[-83.903347,38.769315],[-83.848578,38.747407]]]}}, -{"type":"Feature","id":"21163","properties":{"name":"Meade"},"geometry":{"type":"Polygon","coordinates":[[[-86.307724,38.166851],[-86.001015,37.997066],[-86.148893,37.799896],[-86.488463,38.046358],[-86.461078,38.117559],[-86.307724,38.166851]]]}}, -{"type":"Feature","id":"21165","properties":{"name":"Menifee"},"geometry":{"type":"Polygon","coordinates":[[[-83.498053,38.051835],[-83.43233,38.035405],[-83.492576,37.860142],[-83.607592,37.827281],[-83.6295,37.827281],[-83.766424,37.920389],[-83.760947,37.997066],[-83.498053,38.051835]]]}}, -{"type":"Feature","id":"21167","properties":{"name":"Mercer"},"geometry":{"type":"Polygon","coordinates":[[[-84.796088,37.969681],[-84.708457,37.860142],[-84.713934,37.816327],[-84.746796,37.712265],[-84.856335,37.695834],[-85.02612,37.679403],[-85.031597,37.893004],[-84.796088,37.969681]]]}}, -{"type":"Feature","id":"21169","properties":{"name":"Metcalfe"},"geometry":{"type":"Polygon","coordinates":[[[-85.68883,37.181002],[-85.524521,37.109802],[-85.453321,36.940016],[-85.595722,36.819524],[-85.738122,36.841432],[-85.743599,37.170048],[-85.68883,37.181002]]]}}, -{"type":"Feature","id":"21171","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-85.738122,36.841432],[-85.595722,36.819524],[-85.43689,36.616877],[-85.787415,36.622354],[-85.979107,36.627831],[-85.979107,36.720939],[-85.738122,36.841432]]]}}, -{"type":"Feature","id":"21173","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-84.040271,38.144943],[-83.980024,38.194236],[-83.760947,37.997066],[-83.766424,37.920389],[-83.96907,37.931343],[-84.078609,38.117559],[-84.040271,38.144943]]]}}, -{"type":"Feature","id":"21175","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-83.355653,38.068266],[-83.262545,38.117559],[-83.02156,38.00802],[-82.988698,37.964204],[-83.005129,37.860142],[-83.262545,37.712265],[-83.492576,37.860142],[-83.43233,38.035405],[-83.355653,38.068266]]]}}, -{"type":"Feature","id":"21177","properties":{"name":"Muhlenberg"},"geometry":{"type":"Polygon","coordinates":[[[-87.10188,37.41651],[-86.899233,37.213863],[-86.943049,37.071463],[-86.954003,37.071463],[-87.052588,37.060509],[-87.260711,37.071463],[-87.331912,37.159094],[-87.293573,37.389126],[-87.10188,37.41651]]]}}, -{"type":"Feature","id":"21179","properties":{"name":"Nelson"},"geometry":{"type":"Polygon","coordinates":[[[-85.497137,37.986112],[-85.49166,37.991589],[-85.16852,37.969681],[-85.152089,37.898481],[-85.404029,37.728696],[-85.519044,37.553434],[-85.677876,37.734173],[-85.738122,37.81085],[-85.497137,37.986112]]]}}, -{"type":"Feature","id":"21181","properties":{"name":"Nicholas"},"geometry":{"type":"Polygon","coordinates":[[[-84.001932,38.440698],[-83.980024,38.440698],[-83.848578,38.298298],[-83.980024,38.194236],[-84.193625,38.369498],[-84.100517,38.457129],[-84.001932,38.440698]]]}}, -{"type":"Feature","id":"21183","properties":{"name":"Ohio"},"geometry":{"type":"Polygon","coordinates":[[[-86.822556,37.73965],[-86.63634,37.662973],[-86.592525,37.564388],[-86.614433,37.394602],[-86.899233,37.213863],[-87.10188,37.41651],[-87.036157,37.558911],[-86.822556,37.73965]]]}}, -{"type":"Feature","id":"21185","properties":{"name":"Oldham"},"geometry":{"type":"Polygon","coordinates":[[[-85.639537,38.380452],[-85.431413,38.522852],[-85.316398,38.489991],[-85.283536,38.358544],[-85.469752,38.287344],[-85.639537,38.380452]]]}}, -{"type":"Feature","id":"21187","properties":{"name":"Owen"},"geometry":{"type":"Polygon","coordinates":[[[-84.817996,38.709068],[-84.785134,38.720022],[-84.582488,38.47356],[-84.741319,38.353067],[-84.861812,38.358544],[-84.872765,38.358544],[-85.075412,38.599529],[-84.933012,38.659776],[-84.817996,38.709068]]]}}, -{"type":"Feature","id":"21189","properties":{"name":"Owsley"},"geometry":{"type":"Polygon","coordinates":[[[-83.651408,37.537003],[-83.580208,37.504141],[-83.547346,37.334356],[-83.525438,37.257679],[-83.574731,37.279587],[-83.782854,37.350787],[-83.886916,37.520572],[-83.651408,37.537003]]]}}, -{"type":"Feature","id":"21191","properties":{"name":"Pendleton"},"geometry":{"type":"Polygon","coordinates":[[[-84.231963,38.829561],[-84.204579,38.583099],[-84.401749,38.561191],[-84.478426,38.54476],[-84.533195,38.791222],[-84.418179,38.807653],[-84.231963,38.873376],[-84.231963,38.829561]]]}}, -{"type":"Feature","id":"21193","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-83.125621,37.405556],[-82.999652,37.197433],[-83.120145,37.000263],[-83.180391,37.022171],[-83.509007,37.235771],[-83.525438,37.257679],[-83.547346,37.334356],[-83.125621,37.405556]]]}}, -{"type":"Feature","id":"21195","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-82.145249,37.569865],[-81.969987,37.537003],[-82.315034,37.296018],[-82.55602,37.20291],[-82.566974,37.197433],[-82.731282,37.27411],[-82.709374,37.285064],[-82.561497,37.68488],[-82.331465,37.73965],[-82.145249,37.569865]]]}}, -{"type":"Feature","id":"21197","properties":{"name":"Powell"},"geometry":{"type":"Polygon","coordinates":[[[-83.990978,37.914912],[-83.96907,37.931343],[-83.766424,37.920389],[-83.6295,37.827281],[-83.706177,37.717742],[-83.722608,37.717742],[-84.001932,37.838235],[-83.990978,37.914912]]]}}, -{"type":"Feature","id":"21199","properties":{"name":"Pulaski"},"geometry":{"type":"Polygon","coordinates":[[[-84.670119,37.27411],[-84.500334,37.328879],[-84.286733,37.153617],[-84.357933,36.961924],[-84.577011,36.868816],[-84.807042,36.989309],[-84.834427,36.994786],[-84.90015,37.115279],[-84.719411,37.235771],[-84.670119,37.27411]]]}}, -{"type":"Feature","id":"21201","properties":{"name":"Robertson"},"geometry":{"type":"Polygon","coordinates":[[[-83.96907,38.583099],[-83.930732,38.489991],[-83.980024,38.440698],[-84.001932,38.440698],[-84.100517,38.457129],[-84.160763,38.555714],[-83.990978,38.594052],[-83.96907,38.583099]]]}}, -{"type":"Feature","id":"21203","properties":{"name":"Rockcastle"},"geometry":{"type":"Polygon","coordinates":[[[-84.231963,37.520572],[-84.199102,37.520572],[-84.138855,37.317925],[-84.138855,37.306971],[-84.286733,37.153617],[-84.500334,37.328879],[-84.445564,37.48771],[-84.346979,37.537003],[-84.231963,37.520572]]]}}, -{"type":"Feature","id":"21205","properties":{"name":"Rowan"},"geometry":{"type":"Polygon","coordinates":[[[-83.410422,38.396883],[-83.339222,38.320205],[-83.246114,38.194236],[-83.262545,38.117559],[-83.355653,38.068266],[-83.43233,38.035405],[-83.498053,38.051835],[-83.634977,38.188759],[-83.454238,38.380452],[-83.410422,38.396883]]]}}, -{"type":"Feature","id":"21207","properties":{"name":"Russell"},"geometry":{"type":"Polygon","coordinates":[[[-85.042551,37.186479],[-84.90015,37.115279],[-84.834427,36.994786],[-85.064458,36.857862],[-85.217813,36.852385],[-85.234244,36.923586],[-85.042551,37.186479]]]}}, -{"type":"Feature","id":"21209","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-84.555103,38.495467],[-84.440087,38.281867],[-84.401749,38.20519],[-84.626303,38.117559],[-84.724888,38.194236],[-84.741319,38.353067],[-84.582488,38.47356],[-84.555103,38.495467]]]}}, -{"type":"Feature","id":"21211","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-85.283536,38.358544],[-84.998735,38.336636],[-85.02612,38.128512],[-85.102797,38.035405],[-85.425936,38.144943],[-85.469752,38.287344],[-85.283536,38.358544]]]}}, -{"type":"Feature","id":"21213","properties":{"name":"Simpson"},"geometry":{"type":"Polygon","coordinates":[[[-86.608956,36.885247],[-86.406309,36.775708],[-86.411786,36.649739],[-86.56514,36.633308],[-86.76231,36.649739],[-86.608956,36.885247]]]}}, -{"type":"Feature","id":"21215","properties":{"name":"Spencer"},"geometry":{"type":"Polygon","coordinates":[[[-85.425936,38.144943],[-85.102797,38.035405],[-85.16852,37.969681],[-85.49166,37.991589],[-85.431413,38.117559],[-85.425936,38.144943]]]}}, -{"type":"Feature","id":"21217","properties":{"name":"Taylor"},"geometry":{"type":"Polygon","coordinates":[[[-85.584768,37.47128],[-85.464275,37.465803],[-85.075412,37.411033],[-85.163043,37.312448],[-85.354736,37.191956],[-85.584768,37.47128]]]}}, -{"type":"Feature","id":"21219","properties":{"name":"Todd"},"geometry":{"type":"Polygon","coordinates":[[[-87.260711,37.071463],[-87.260711,37.071463],[-87.052588,37.060509],[-87.058065,36.644262],[-87.112834,36.644262],[-87.337389,36.644262],[-87.260711,37.071463]]]}}, -{"type":"Feature","id":"21221","properties":{"name":"Trigg"},"geometry":{"type":"Polygon","coordinates":[[[-87.731728,37.000263],[-87.69339,36.638785],[-88.071299,36.677123],[-88.109637,36.748324],[-88.15893,36.868816],[-87.879606,36.961924],[-87.731728,37.000263]]]}}, -{"type":"Feature","id":"21223","properties":{"name":"Trimble"},"geometry":{"type":"Polygon","coordinates":[[[-85.425936,38.588575],[-85.332828,38.736453],[-85.16852,38.583099],[-85.316398,38.489991],[-85.431413,38.522852],[-85.425936,38.588575]]]}}, -{"type":"Feature","id":"21225","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-88.027483,37.799896],[-87.928898,37.903958],[-87.731728,37.635588],[-87.934375,37.482234],[-88.060345,37.504141],[-88.131545,37.575342],[-88.027483,37.799896]]]}}, -{"type":"Feature","id":"21227","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-86.400832,37.170048],[-86.116031,37.060509],[-86.165323,36.934539],[-86.22557,36.912632],[-86.406309,36.775708],[-86.608956,36.885247],[-86.674679,37.000263],[-86.400832,37.170048]]]}}, -{"type":"Feature","id":"21229","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-85.152089,37.898481],[-85.031597,37.893004],[-85.02612,37.679403],[-85.031597,37.630111],[-85.404029,37.728696],[-85.152089,37.898481]]]}}, -{"type":"Feature","id":"21231","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-84.807042,36.989309],[-84.577011,36.868816],[-84.779657,36.605923],[-84.785134,36.605923],[-84.976827,36.616877],[-85.064458,36.857862],[-84.834427,36.994786],[-84.807042,36.989309]]]}}, -{"type":"Feature","id":"21233","properties":{"name":"Webster"},"geometry":{"type":"Polygon","coordinates":[[[-87.49622,37.646542],[-87.375727,37.569865],[-87.813882,37.350787],[-87.802929,37.378172],[-87.934375,37.482234],[-87.731728,37.635588],[-87.49622,37.646542]]]}}, -{"type":"Feature","id":"21235","properties":{"name":"Whitley"},"geometry":{"type":"Polygon","coordinates":[[[-84.122425,36.967401],[-84.089563,36.956447],[-83.875962,36.688077],[-83.930732,36.589492],[-83.985501,36.589492],[-84.226487,36.589492],[-84.297687,36.945493],[-84.122425,36.967401]]]}}, -{"type":"Feature","id":"21237","properties":{"name":"Wolfe"},"geometry":{"type":"Polygon","coordinates":[[[-83.607592,37.827281],[-83.492576,37.860142],[-83.262545,37.712265],[-83.246114,37.668449],[-83.377561,37.695834],[-83.519961,37.641065],[-83.706177,37.717742],[-83.6295,37.827281],[-83.607592,37.827281]]]}}, -{"type":"Feature","id":"21239","properties":{"name":"Woodford"},"geometry":{"type":"Polygon","coordinates":[[[-84.867289,38.117559],[-84.724888,38.194236],[-84.626303,38.117559],[-84.659165,38.002543],[-84.708457,37.860142],[-84.796088,37.969681],[-84.867289,38.117559]]]}}, -{"type":"Feature","id":"22001","properties":{"name":"Acadia"},"geometry":{"type":"Polygon","coordinates":[[[-92.63359,30.482704],[-92.49119,30.482704],[-92.140665,30.296488],[-92.283066,30.14861],[-92.628113,30.093841],[-92.63359,30.482704]]]}}, -{"type":"Feature","id":"22003","properties":{"name":"Allen"},"geometry":{"type":"Polygon","coordinates":[[[-92.660975,30.898951],[-92.595251,30.893474],[-92.628113,30.488181],[-92.770513,30.488181],[-93.131992,30.422457],[-92.978637,30.877043],[-92.825283,30.887997],[-92.660975,30.898951]]]}}, -{"type":"Feature","id":"22005","properties":{"name":"Ascension"},"geometry":{"type":"Polygon","coordinates":[[[-90.891923,30.34578],[-90.634507,30.219811],[-90.639984,30.165041],[-90.963123,30.066456],[-91.078139,30.07741],[-91.105524,30.060979],[-91.023369,30.323872],[-90.891923,30.34578]]]}}, -{"type":"Feature","id":"22007","properties":{"name":"Assumption"},"geometry":{"type":"Polygon","coordinates":[[[-91.078139,30.07741],[-90.963123,30.066456],[-90.886446,29.907625],[-91.006939,29.715932],[-91.083616,29.628301],[-91.100047,29.699501],[-91.253401,29.973348],[-91.226016,30.022641],[-91.105524,30.060979],[-91.078139,30.07741]]]}}, -{"type":"Feature","id":"22009","properties":{"name":"Avoyelles"},"geometry":{"type":"Polygon","coordinates":[[[-92.085896,31.337106],[-92.009219,31.326153],[-91.833957,31.265906],[-91.724418,31.046829],[-91.751803,31.019444],[-91.762756,31.00849],[-91.817526,30.849659],[-92.085896,30.849659],[-92.211866,30.849659],[-92.283066,30.964674],[-92.085896,31.337106]]]}}, -{"type":"Feature","id":"22011","properties":{"name":"Beauregard"},"geometry":{"type":"Polygon","coordinates":[[[-93.011499,30.877043],[-92.978637,30.877043],[-93.131992,30.422457],[-93.131992,30.40055],[-93.460608,30.488181],[-93.739932,30.40055],[-93.559193,30.86609],[-93.011499,30.877043]]]}}, -{"type":"Feature","id":"22013","properties":{"name":"Bienville"},"geometry":{"type":"Polygon","coordinates":[[[-92.912914,32.585849],[-92.880052,32.585849],[-92.77599,32.454402],[-92.814329,32.147694],[-92.940299,32.147694],[-93.131992,32.147694],[-93.186761,32.147694],[-93.427746,32.235325],[-93.372977,32.410587],[-93.181284,32.585849],[-92.912914,32.585849]]]}}, -{"type":"Feature","id":"22015","properties":{"name":"Bossier"},"geometry":{"type":"Polygon","coordinates":[[[-93.805655,33.018527],[-93.520854,33.018527],[-93.372977,32.410587],[-93.427746,32.235325],[-93.471562,32.235325],[-93.816609,33.018527],[-93.805655,33.018527]]]}}, -{"type":"Feature","id":"22017","properties":{"name":"Caddo"},"geometry":{"type":"Polygon","coordinates":[[[-93.816609,33.018527],[-93.471562,32.235325],[-93.613962,32.235325],[-93.750886,32.339387],[-94.041164,32.196986],[-94.041164,32.394156],[-94.041164,32.695388],[-94.041164,32.881604],[-94.041164,33.018527],[-93.816609,33.018527]]]}}, -{"type":"Feature","id":"22019","properties":{"name":"Calcasieu"},"geometry":{"type":"Polygon","coordinates":[[[-93.460608,30.488181],[-93.131992,30.40055],[-92.995068,30.039072],[-93.372977,30.050025],[-93.723501,30.050025],[-93.70707,30.247195],[-93.739932,30.40055],[-93.460608,30.488181]]]}}, -{"type":"Feature","id":"22021","properties":{"name":"Caldwell"},"geometry":{"type":"Polygon","coordinates":[[[-92.16805,32.27914],[-92.036603,32.27914],[-91.894203,32.153171],[-91.888726,31.972432],[-92.003742,31.928616],[-92.184481,31.928616],[-92.31045,31.928616],[-92.31045,32.147694],[-92.31045,32.27914],[-92.16805,32.27914]]]}}, -{"type":"Feature","id":"22023","properties":{"name":"Cameron"},"geometry":{"type":"Polygon","coordinates":[[[-93.372977,30.050025],[-92.995068,30.039072],[-92.737652,30.039072],[-92.617159,29.579009],[-93.2251,29.776178],[-93.838517,29.688547],[-93.854948,29.863809],[-93.723501,30.050025],[-93.372977,30.050025]]]}}, -{"type":"Feature","id":"22025","properties":{"name":"Catahoula"},"geometry":{"type":"Polygon","coordinates":[[[-91.647741,31.972432],[-91.57654,31.8848],[-91.543679,31.753354],[-91.833957,31.265906],[-92.009219,31.326153],[-92.003742,31.928616],[-91.888726,31.972432],[-91.647741,31.972432]]]}}, -{"type":"Feature","id":"22027","properties":{"name":"Claiborne"},"geometry":{"type":"Polygon","coordinates":[[[-93.236053,33.018527],[-92.989591,33.018527],[-92.726698,33.01305],[-92.726698,32.761111],[-92.880052,32.585849],[-92.912914,32.585849],[-93.181284,32.585849],[-93.236053,33.018527]]]}}, -{"type":"Feature","id":"22029","properties":{"name":"Concordia"},"geometry":{"type":"Polygon","coordinates":[[[-91.428663,31.753354],[-91.379371,31.731446],[-91.587494,31.189229],[-91.636787,30.997536],[-91.664172,30.970151],[-91.658695,30.992059],[-91.724418,31.046829],[-91.833957,31.265906],[-91.543679,31.753354],[-91.428663,31.753354]]]}}, -{"type":"Feature","id":"22031","properties":{"name":"De Soto"},"geometry":{"type":"Polygon","coordinates":[[[-93.750886,32.339387],[-93.613962,32.235325],[-93.356546,31.934093],[-93.4387,31.846462],[-93.619439,31.846462],[-93.882332,31.846462],[-94.013779,31.977908],[-94.041164,32.196986],[-93.750886,32.339387]]]}}, -{"type":"Feature","id":"22033","properties":{"name":"East Baton Rouge"},"geometry":{"type":"Polygon","coordinates":[[[-90.864538,30.718212],[-90.848107,30.718212],[-90.908354,30.647012],[-90.891923,30.34578],[-91.023369,30.323872],[-91.143862,30.323872],[-91.297217,30.647012],[-90.864538,30.718212]]]}}, -{"type":"Feature","id":"22035","properties":{"name":"East Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-91.16577,33.002096],[-91.045277,32.574895],[-91.067185,32.563941],[-91.368417,32.536556],[-91.456048,32.536556],[-91.445094,32.580372],[-91.264355,33.007573],[-91.16577,33.002096]]]}}, -{"type":"Feature","id":"22037","properties":{"name":"East Feliciana"},"geometry":{"type":"Polygon","coordinates":[[[-91.061708,30.997536],[-90.8262,30.997536],[-90.848107,30.718212],[-90.864538,30.718212],[-91.297217,30.647012],[-91.302693,30.652489],[-91.176724,30.997536],[-91.061708,30.997536]]]}}, -{"type":"Feature","id":"22039","properties":{"name":"Evangeline"},"geometry":{"type":"Polygon","coordinates":[[[-92.387128,31.003013],[-92.283066,30.964674],[-92.211866,30.849659],[-92.49119,30.482704],[-92.63359,30.482704],[-92.628113,30.488181],[-92.595251,30.893474],[-92.387128,31.003013]]]}}, -{"type":"Feature","id":"22041","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-91.57654,32.40511],[-91.477956,32.40511],[-91.494386,32.202463],[-91.57654,31.8848],[-91.647741,31.972432],[-91.888726,31.972432],[-91.894203,32.153171],[-91.57654,32.40511]]]}}, -{"type":"Feature","id":"22043","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-92.36522,31.797169],[-92.195435,31.479507],[-92.721221,31.517845],[-92.97316,31.709538],[-92.36522,31.797169]]]}}, -{"type":"Feature","id":"22045","properties":{"name":"Iberia"},"geometry":{"type":"Polygon","coordinates":[[[-91.724418,30.121226],[-91.368417,30.060979],[-91.226016,30.022641],[-91.253401,29.973348],[-91.472479,29.956917],[-91.532725,29.951441],[-91.877772,29.721409],[-91.97088,29.803563],[-91.965403,30.033595],[-91.948972,30.071933],[-91.724418,30.121226]]]}}, -{"type":"Feature","id":"22047","properties":{"name":"Iberville"},"geometry":{"type":"Polygon","coordinates":[[[-91.521771,30.499135],[-91.483432,30.499135],[-91.143862,30.323872],[-91.023369,30.323872],[-91.105524,30.060979],[-91.226016,30.022641],[-91.368417,30.060979],[-91.70251,30.499135],[-91.521771,30.499135]]]}}, -{"type":"Feature","id":"22049","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-92.578821,32.498218],[-92.414512,32.498218],[-92.31045,32.27914],[-92.31045,32.147694],[-92.814329,32.147694],[-92.77599,32.454402],[-92.578821,32.498218]]]}}, -{"type":"Feature","id":"22051","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-90.278506,30.230764],[-90.245644,30.225288],[-90.103244,30.192426],[-90.010136,29.896671],[-89.977274,29.447562],[-90.032043,29.431131],[-90.229213,29.694024],[-90.278506,30.230764]]]}}, -{"type":"Feature","id":"22053","properties":{"name":"Jefferson Davis"},"geometry":{"type":"Polygon","coordinates":[[[-92.770513,30.488181],[-92.628113,30.488181],[-92.63359,30.482704],[-92.628113,30.093841],[-92.737652,30.039072],[-92.995068,30.039072],[-93.131992,30.40055],[-93.131992,30.422457],[-92.770513,30.488181]]]}}, -{"type":"Feature","id":"22055","properties":{"name":"Lafayette"},"geometry":{"type":"Polygon","coordinates":[[[-92.053034,30.378642],[-91.987311,30.367688],[-91.948972,30.071933],[-91.965403,30.033595],[-92.250204,30.143133],[-92.283066,30.14861],[-92.140665,30.296488],[-92.053034,30.378642]]]}}, -{"type":"Feature","id":"22057","properties":{"name":"Lafourche"},"geometry":{"type":"Polygon","coordinates":[[[-90.727615,29.913102],[-90.656414,29.891194],[-90.541399,29.891194],[-90.229213,29.694024],[-90.032043,29.431131],[-90.064905,29.212054],[-90.086813,29.162761],[-90.409952,29.195623],[-90.815246,29.776178],[-91.006939,29.715932],[-90.886446,29.907625],[-90.727615,29.913102]]]}}, -{"type":"Feature","id":"22059","properties":{"name":"La Salle"},"geometry":{"type":"Polygon","coordinates":[[[-92.184481,31.928616],[-92.003742,31.928616],[-92.009219,31.326153],[-92.085896,31.337106],[-92.195435,31.479507],[-92.36522,31.797169],[-92.31045,31.928616],[-92.184481,31.928616]]]}}, -{"type":"Feature","id":"22061","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-92.726698,32.761111],[-92.414512,32.580372],[-92.414512,32.498218],[-92.578821,32.498218],[-92.77599,32.454402],[-92.880052,32.585849],[-92.726698,32.761111]]]}}, -{"type":"Feature","id":"22063","properties":{"name":"Livingston"},"geometry":{"type":"Polygon","coordinates":[[[-90.744046,30.652489],[-90.568783,30.652489],[-90.398998,30.285534],[-90.634507,30.219811],[-90.891923,30.34578],[-90.908354,30.647012],[-90.744046,30.652489]]]}}, -{"type":"Feature","id":"22065","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-91.368417,32.536556],[-91.067185,32.563941],[-91.121954,32.213417],[-91.494386,32.202463],[-91.477956,32.40511],[-91.456048,32.536556],[-91.368417,32.536556]]]}}, -{"type":"Feature","id":"22067","properties":{"name":"Morehouse"},"geometry":{"type":"Polygon","coordinates":[[[-92.069465,33.007573],[-91.461525,33.007573],[-91.43414,33.007573],[-91.636787,32.668003],[-91.910634,32.503695],[-91.998265,32.706342],[-92.063988,32.722772],[-92.069465,33.007573]]]}}, -{"type":"Feature","id":"22069","properties":{"name":"Natchitoches"},"geometry":{"type":"Polygon","coordinates":[[[-93.131992,32.147694],[-92.940299,32.147694],[-92.97316,31.709538],[-92.721221,31.517845],[-92.984114,31.34806],[-93.236053,31.364491],[-93.4387,31.846462],[-93.356546,31.934093],[-93.186761,32.147694],[-93.131992,32.147694]]]}}, -{"type":"Feature","id":"22071","properties":{"name":"Orleans"},"geometry":{"type":"Polygon","coordinates":[[[-89.900597,30.192426],[-89.62675,30.14861],[-89.856781,30.00621],[-89.862258,30.000733],[-89.911551,29.869286],[-89.988228,29.907625],[-90.010136,29.896671],[-90.103244,30.192426],[-89.900597,30.192426]]]}}, -{"type":"Feature","id":"22073","properties":{"name":"Ouachita"},"geometry":{"type":"Polygon","coordinates":[[[-91.998265,32.706342],[-91.910634,32.503695],[-92.036603,32.27914],[-92.16805,32.27914],[-92.31045,32.27914],[-92.414512,32.498218],[-92.414512,32.580372],[-92.063988,32.722772],[-91.998265,32.706342]]]}}, -{"type":"Feature","id":"22075","properties":{"name":"Plaquemines"},"geometry":{"type":"Polygon","coordinates":[[[-89.988228,29.907625],[-89.911551,29.869286],[-89.484349,29.622824],[-89.002379,29.179192],[-89.16121,29.009407],[-89.977274,29.447562],[-90.010136,29.896671],[-89.988228,29.907625]]]}}, -{"type":"Feature","id":"22077","properties":{"name":"Pointe Coupee"},"geometry":{"type":"Polygon","coordinates":[[[-91.762756,31.00849],[-91.751803,31.019444],[-91.658695,30.992059],[-91.664172,30.970151],[-91.330078,30.657966],[-91.483432,30.499135],[-91.521771,30.499135],[-91.70251,30.499135],[-91.75728,30.499135],[-91.817526,30.849659],[-91.762756,31.00849]]]}}, -{"type":"Feature","id":"22079","properties":{"name":"Rapides"},"geometry":{"type":"Polygon","coordinates":[[[-92.721221,31.517845],[-92.195435,31.479507],[-92.085896,31.337106],[-92.283066,30.964674],[-92.387128,31.003013],[-92.595251,30.893474],[-92.660975,30.898951],[-92.825283,30.887997],[-92.984114,31.34806],[-92.721221,31.517845]]]}}, -{"type":"Feature","id":"22081","properties":{"name":"Red River"},"geometry":{"type":"Polygon","coordinates":[[[-93.471562,32.235325],[-93.427746,32.235325],[-93.186761,32.147694],[-93.356546,31.934093],[-93.613962,32.235325],[-93.471562,32.235325]]]}}, -{"type":"Feature","id":"22083","properties":{"name":"Richland"},"geometry":{"type":"Polygon","coordinates":[[[-91.598448,32.668003],[-91.445094,32.580372],[-91.456048,32.536556],[-91.477956,32.40511],[-91.57654,32.40511],[-91.894203,32.153171],[-92.036603,32.27914],[-91.910634,32.503695],[-91.636787,32.668003],[-91.598448,32.668003]]]}}, -{"type":"Feature","id":"22085","properties":{"name":"Sabine"},"geometry":{"type":"Polygon","coordinates":[[[-93.619439,31.846462],[-93.4387,31.846462],[-93.236053,31.364491],[-93.553716,31.183752],[-93.603008,31.178275],[-93.83304,31.583569],[-93.882332,31.846462],[-93.619439,31.846462]]]}}, -{"type":"Feature","id":"22087","properties":{"name":"St. Bernard"},"geometry":{"type":"Polygon","coordinates":[[[-89.862258,30.000733],[-89.856781,30.00621],[-89.369334,29.913102],[-89.484349,29.622824],[-89.911551,29.869286],[-89.862258,30.000733]]]}}, -{"type":"Feature","id":"22089","properties":{"name":"St. Charles"},"geometry":{"type":"Polygon","coordinates":[[[-90.420906,30.060979],[-90.278506,30.230764],[-90.229213,29.694024],[-90.541399,29.891194],[-90.420906,30.060979]]]}}, -{"type":"Feature","id":"22091","properties":{"name":"St. Helena"},"geometry":{"type":"Polygon","coordinates":[[[-90.568783,30.997536],[-90.568783,30.652489],[-90.744046,30.652489],[-90.908354,30.647012],[-90.848107,30.718212],[-90.8262,30.997536],[-90.568783,30.997536]]]}}, -{"type":"Feature","id":"22093","properties":{"name":"St. James"},"geometry":{"type":"Polygon","coordinates":[[[-90.639984,30.165041],[-90.656414,29.891194],[-90.727615,29.913102],[-90.886446,29.907625],[-90.963123,30.066456],[-90.639984,30.165041]]]}}, -{"type":"Feature","id":"22095","properties":{"name":"St. John the Baptist"},"geometry":{"type":"Polygon","coordinates":[[[-90.398998,30.285534],[-90.278506,30.230764],[-90.420906,30.060979],[-90.541399,29.891194],[-90.656414,29.891194],[-90.639984,30.165041],[-90.634507,30.219811],[-90.398998,30.285534]]]}}, -{"type":"Feature","id":"22097","properties":{"name":"St. Landry"},"geometry":{"type":"Polygon","coordinates":[[[-92.085896,30.849659],[-91.817526,30.849659],[-91.75728,30.499135],[-91.987311,30.367688],[-92.053034,30.378642],[-92.140665,30.296488],[-92.49119,30.482704],[-92.211866,30.849659],[-92.085896,30.849659]]]}}, -{"type":"Feature","id":"22099","properties":{"name":"St. Martin"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-91.75728,30.499135],[-91.70251,30.499135],[-91.368417,30.060979],[-91.724418,30.121226],[-91.948972,30.071933],[-91.987311,30.367688],[-91.75728,30.499135]]],[[[-91.472479,29.956917],[-91.253401,29.973348],[-91.100047,29.699501],[-91.472479,29.956917]]]]}}, -{"type":"Feature","id":"22101","properties":{"name":"St. Mary"},"geometry":{"type":"Polygon","coordinates":[[[-91.532725,29.951441],[-91.472479,29.956917],[-91.100047,29.699501],[-91.083616,29.628301],[-91.275309,29.474947],[-91.877772,29.721409],[-91.532725,29.951441]]]}}, -{"type":"Feature","id":"22103","properties":{"name":"St. Tammany"},"geometry":{"type":"Polygon","coordinates":[[[-90.256598,30.712735],[-89.84035,30.663443],[-89.686996,30.460796],[-89.522688,30.181472],[-89.62675,30.14861],[-89.900597,30.192426],[-90.103244,30.192426],[-90.245644,30.225288],[-90.256598,30.712735]]]}}, -{"type":"Feature","id":"22105","properties":{"name":"Tangipahoa"},"geometry":{"type":"Polygon","coordinates":[[[-90.371614,30.997536],[-90.349706,31.003013],[-90.256598,30.712735],[-90.245644,30.225288],[-90.278506,30.230764],[-90.398998,30.285534],[-90.568783,30.652489],[-90.568783,30.997536],[-90.546876,30.997536],[-90.371614,30.997536]]]}}, -{"type":"Feature","id":"22107","properties":{"name":"Tensas"},"geometry":{"type":"Polygon","coordinates":[[[-91.494386,32.202463],[-91.121954,32.213417],[-91.050754,32.125786],[-91.028846,32.120309],[-91.028846,32.114832],[-91.247924,31.86837],[-91.346509,31.753354],[-91.379371,31.731446],[-91.428663,31.753354],[-91.543679,31.753354],[-91.57654,31.8848],[-91.494386,32.202463]]]}}, -{"type":"Feature","id":"22109","properties":{"name":"Terrebonne"},"geometry":{"type":"Polygon","coordinates":[[[-90.815246,29.776178],[-90.409952,29.195623],[-90.837154,29.036791],[-91.275309,29.474947],[-91.083616,29.628301],[-91.006939,29.715932],[-90.815246,29.776178]]]}}, -{"type":"Feature","id":"22111","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-92.710267,33.01305],[-92.069465,33.007573],[-92.063988,32.722772],[-92.414512,32.580372],[-92.726698,32.761111],[-92.726698,33.01305],[-92.710267,33.01305]]]}}, -{"type":"Feature","id":"22113","properties":{"name":"Vermilion"},"geometry":{"type":"Polygon","coordinates":[[[-92.250204,30.143133],[-91.965403,30.033595],[-91.97088,29.803563],[-91.998265,29.61187],[-92.04208,29.579009],[-92.617159,29.579009],[-92.737652,30.039072],[-92.628113,30.093841],[-92.283066,30.14861],[-92.250204,30.143133]]]}}, -{"type":"Feature","id":"22115","properties":{"name":"Vernon"},"geometry":{"type":"Polygon","coordinates":[[[-93.236053,31.364491],[-92.984114,31.34806],[-92.825283,30.887997],[-92.978637,30.877043],[-93.011499,30.877043],[-93.559193,30.86609],[-93.553716,31.183752],[-93.236053,31.364491]]]}}, -{"type":"Feature","id":"22117","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-89.834873,31.003013],[-89.730812,31.003013],[-89.84035,30.663443],[-90.256598,30.712735],[-90.349706,31.003013],[-90.262075,31.003013],[-89.834873,31.003013]]]}}, -{"type":"Feature","id":"22119","properties":{"name":"Webster"},"geometry":{"type":"Polygon","coordinates":[[[-93.49347,33.018527],[-93.487993,33.018527],[-93.236053,33.018527],[-93.181284,32.585849],[-93.372977,32.410587],[-93.520854,33.018527],[-93.49347,33.018527]]]}}, -{"type":"Feature","id":"22121","properties":{"name":"West Baton Rouge"},"geometry":{"type":"Polygon","coordinates":[[[-91.330078,30.657966],[-91.302693,30.652489],[-91.297217,30.647012],[-91.143862,30.323872],[-91.483432,30.499135],[-91.330078,30.657966]]]}}, -{"type":"Feature","id":"22123","properties":{"name":"West Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-91.30817,33.007573],[-91.264355,33.007573],[-91.445094,32.580372],[-91.598448,32.668003],[-91.636787,32.668003],[-91.43414,33.007573],[-91.30817,33.007573]]]}}, -{"type":"Feature","id":"22125","properties":{"name":"West Feliciana"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-91.724418,31.046829],[-91.658695,30.992059],[-91.751803,31.019444],[-91.724418,31.046829]]],[[[-91.636787,30.997536],[-91.176724,30.997536],[-91.302693,30.652489],[-91.330078,30.657966],[-91.664172,30.970151],[-91.636787,30.997536]]]]}}, -{"type":"Feature","id":"22127","properties":{"name":"Winn"},"geometry":{"type":"Polygon","coordinates":[[[-92.940299,32.147694],[-92.814329,32.147694],[-92.31045,32.147694],[-92.31045,31.928616],[-92.36522,31.797169],[-92.97316,31.709538],[-92.940299,32.147694]]]}}, -{"type":"Feature","id":"23001","properties":{"name":"Androscoggin"},"geometry":{"type":"Polygon","coordinates":[[[-70.172658,44.481763],[-70.128842,44.48724],[-70.002872,44.125762],[-70.035734,43.977885],[-70.479366,44.032654],[-70.238381,44.459856],[-70.172658,44.481763]]]}}, -{"type":"Feature","id":"23003","properties":{"name":"Aroostook"},"geometry":{"type":"Polygon","coordinates":[[[-67.806619,45.681213],[-68.047605,45.637398],[-68.43099,45.577151],[-68.513145,46.382262],[-68.819853,46.393216],[-68.819853,46.573955],[-69.723548,46.573955],[-70.02478,46.573955],[-69.225147,47.461219],[-68.902007,47.176418],[-68.233821,47.357157],[-67.790188,47.066879],[-67.806619,45.681213]]]}}, -{"type":"Feature","id":"23005","properties":{"name":"Cumberland"},"geometry":{"type":"Polygon","coordinates":[[[-70.676536,44.142193],[-70.479366,44.032654],[-70.035734,43.977885],[-69.887857,43.775238],[-70.353397,43.534253],[-70.780598,43.813577],[-70.676536,44.142193]]]}}, -{"type":"Feature","id":"23007","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-70.550566,45.670259],[-70.41912,45.144473],[-69.931672,44.61321],[-70.128842,44.48724],[-70.172658,44.481763],[-70.238381,44.459856],[-70.769644,44.733703],[-70.835367,45.27592],[-70.550566,45.670259]]]}}, -{"type":"Feature","id":"23009","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-68.058559,45.254012],[-67.954497,44.41604],[-68.797945,44.470809],[-68.814376,44.68441],[-68.058559,45.254012]]]}}, -{"type":"Feature","id":"23011","properties":{"name":"Kennebec"},"geometry":{"type":"Polygon","coordinates":[[[-69.581148,44.706318],[-69.471609,44.695364],[-69.504471,44.34484],[-69.75641,44.136716],[-70.002872,44.125762],[-70.128842,44.48724],[-69.931672,44.61321],[-69.581148,44.706318]]]}}, -{"type":"Feature","id":"23013","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-69.411363,44.328409],[-69.027977,44.251732],[-69.373024,43.966931],[-69.411363,44.328409]]]}}, -{"type":"Feature","id":"23015","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-69.411363,44.328409],[-69.373024,43.966931],[-69.696164,43.82453],[-69.75641,44.136716],[-69.504471,44.34484],[-69.411363,44.328409]]]}}, -{"type":"Feature","id":"23017","properties":{"name":"Oxford"},"geometry":{"type":"Polygon","coordinates":[[[-70.835367,45.27592],[-70.769644,44.733703],[-70.238381,44.459856],[-70.479366,44.032654],[-70.676536,44.142193],[-70.780598,43.813577],[-70.988722,43.791669],[-71.010629,44.284593],[-71.08183,45.303304],[-70.835367,45.27592]]]}}, -{"type":"Feature","id":"23019","properties":{"name":"Penobscot"},"geometry":{"type":"Polygon","coordinates":[[[-68.513145,46.382262],[-68.43099,45.577151],[-68.047605,45.637398],[-68.058559,45.254012],[-68.814376,44.68441],[-69.268962,44.722749],[-69.356593,45.073273],[-68.776038,45.243058],[-68.819853,46.393216],[-68.513145,46.382262]]]}}, -{"type":"Feature","id":"23021","properties":{"name":"Piscataquis"},"geometry":{"type":"Polygon","coordinates":[[[-68.819853,46.393216],[-68.776038,45.243058],[-69.356593,45.073273],[-69.619487,45.013027],[-69.822133,45.74146],[-69.723548,46.573955],[-68.819853,46.573955],[-68.819853,46.393216]]]}}, -{"type":"Feature","id":"23023","properties":{"name":"Sagadahoc"},"geometry":{"type":"Polygon","coordinates":[[[-69.75641,44.136716],[-69.696164,43.82453],[-69.887857,43.775238],[-70.035734,43.977885],[-70.002872,44.125762],[-69.75641,44.136716]]]}}, -{"type":"Feature","id":"23025","properties":{"name":"Somerset"},"geometry":{"type":"Polygon","coordinates":[[[-69.723548,46.573955],[-69.822133,45.74146],[-69.619487,45.013027],[-69.356593,45.073273],[-69.268962,44.722749],[-69.471609,44.695364],[-69.581148,44.706318],[-69.931672,44.61321],[-70.41912,45.144473],[-70.550566,45.670259],[-70.02478,46.573955],[-69.723548,46.573955]]]}}, -{"type":"Feature","id":"23027","properties":{"name":"Waldo"},"geometry":{"type":"Polygon","coordinates":[[[-69.471609,44.695364],[-69.268962,44.722749],[-68.814376,44.68441],[-68.797945,44.470809],[-69.027977,44.251732],[-69.411363,44.328409],[-69.504471,44.34484],[-69.471609,44.695364]]]}}, -{"type":"Feature","id":"23029","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-67.954497,44.41604],[-68.058559,45.254012],[-68.047605,45.637398],[-67.806619,45.681213],[-66.979601,44.804903],[-67.954497,44.41604]]]}}, -{"type":"Feature","id":"23031","properties":{"name":"York"},"geometry":{"type":"Polygon","coordinates":[[[-70.780598,43.813577],[-70.353397,43.534253],[-70.703921,43.057759],[-70.818936,43.123482],[-70.961337,43.53973],[-70.988722,43.791669],[-70.780598,43.813577]]]}}, -{"type":"Feature","id":"24001","properties":{"name":"Allegany"},"geometry":{"type":"Polygon","coordinates":[[[-78.809792,39.722302],[-78.382591,39.722302],[-78.344253,39.722302],[-78.333299,39.634671],[-78.470222,39.514178],[-78.656438,39.536086],[-78.738592,39.623717],[-79.067209,39.47584],[-78.930285,39.722302],[-78.809792,39.722302]]]}}, -{"type":"Feature","id":"24003","properties":{"name":"Anne Arundel"},"geometry":{"type":"Polygon","coordinates":[[[-76.619016,39.234854],[-76.531385,39.20747],[-76.531385,38.714545],[-76.635447,38.769315],[-76.68474,38.747407],[-76.838094,39.103408],[-76.695693,39.212947],[-76.619016,39.234854],[-76.619016,39.234854]]]}}, -{"type":"Feature","id":"24005","properties":{"name":"Baltimore"},"geometry":{"type":"Polygon","coordinates":[[[-76.70117,39.722302],[-76.569724,39.722302],[-76.328738,39.355347],[-76.525908,39.218424],[-76.651878,39.371778],[-76.619016,39.234854],[-76.695693,39.212947],[-76.881909,39.34987],[-76.788801,39.722302],[-76.70117,39.722302]]]}}, -{"type":"Feature","id":"24009","properties":{"name":"Calvert"},"geometry":{"type":"Polygon","coordinates":[[[-76.635447,38.769315],[-76.531385,38.714545],[-76.405416,38.320205],[-76.673786,38.500944],[-76.673786,38.533806],[-76.68474,38.747407],[-76.635447,38.769315]]]}}, -{"type":"Feature","id":"24011","properties":{"name":"Caroline"},"geometry":{"type":"Polygon","coordinates":[[[-75.748183,39.141746],[-75.748183,39.141746],[-75.720798,38.829561],[-75.709844,38.637868],[-75.841291,38.703591],[-75.945353,38.676207],[-75.95083,38.917192],[-75.748183,39.141746]]]}}, -{"type":"Feature","id":"24013","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-76.788801,39.722302],[-76.881909,39.34987],[-77.079079,39.366301],[-77.16671,39.355347],[-77.216003,39.722302],[-76.996925,39.722302],[-76.788801,39.722302]]]}}, -{"type":"Feature","id":"24015","properties":{"name":"Cecil"},"geometry":{"type":"Polygon","coordinates":[[[-75.808429,39.722302],[-75.786521,39.722302],[-75.764614,39.377255],[-76.000122,39.377255],[-76.076799,39.541563],[-76.235631,39.722302],[-76.137046,39.722302],[-75.808429,39.722302]]]}}, -{"type":"Feature","id":"24017","properties":{"name":"Charles"},"geometry":{"type":"Polygon","coordinates":[[[-77.046218,38.61596],[-76.673786,38.533806],[-76.673786,38.500944],[-76.706647,38.506421],[-76.832617,38.298298],[-77.128372,38.632391],[-77.084556,38.709068],[-77.046218,38.61596]]]}}, -{"type":"Feature","id":"24019","properties":{"name":"Dorchester"},"geometry":{"type":"Polygon","coordinates":[[[-75.841291,38.703591],[-75.709844,38.637868],[-75.69889,38.561191],[-75.813906,38.489991],[-75.923445,38.265436],[-76.153476,38.632391],[-75.945353,38.676207],[-75.841291,38.703591]]]}}, -{"type":"Feature","id":"24021","properties":{"name":"Frederick"},"geometry":{"type":"Polygon","coordinates":[[[-77.467942,39.722302],[-77.456988,39.722302],[-77.216003,39.722302],[-77.16671,39.355347],[-77.16671,39.355347],[-77.243388,39.317009],[-77.456988,39.218424],[-77.676066,39.322485],[-77.467942,39.722302]]]}}, -{"type":"Feature","id":"24023","properties":{"name":"Garrett"},"geometry":{"type":"Polygon","coordinates":[[[-78.930285,39.722302],[-79.067209,39.47584],[-79.275332,39.327962],[-79.488933,39.20747],[-79.477979,39.722302],[-79.390348,39.722302],[-78.930285,39.722302]]]}}, -{"type":"Feature","id":"24025","properties":{"name":"Harford"},"geometry":{"type":"Polygon","coordinates":[[[-76.241107,39.722302],[-76.235631,39.722302],[-76.076799,39.541563],[-76.328738,39.355347],[-76.569724,39.722302],[-76.241107,39.722302]]]}}, -{"type":"Feature","id":"24027","properties":{"name":"Howard"},"geometry":{"type":"Polygon","coordinates":[[[-77.079079,39.366301],[-76.881909,39.34987],[-76.695693,39.212947],[-76.838094,39.103408],[-76.887386,39.130793],[-77.16671,39.355347],[-77.16671,39.355347],[-77.079079,39.366301]]]}}, -{"type":"Feature","id":"24029","properties":{"name":"Kent"},"geometry":{"type":"Polygon","coordinates":[[[-76.000122,39.377255],[-75.764614,39.377255],[-75.759137,39.295101],[-75.75366,39.245808],[-75.846768,39.256762],[-76.158953,39.092454],[-76.000122,39.377255]]]}}, -{"type":"Feature","id":"24031","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-77.243388,39.317009],[-77.16671,39.355347],[-76.887386,39.130793],[-77.002402,38.966484],[-77.035264,38.993869],[-77.117418,38.933623],[-77.331019,39.059592],[-77.456988,39.218424],[-77.243388,39.317009]]]}}, -{"type":"Feature","id":"24033","properties":{"name":"Prince George's"},"geometry":{"type":"Polygon","coordinates":[[[-76.887386,39.130793],[-76.838094,39.103408],[-76.68474,38.747407],[-76.673786,38.533806],[-77.046218,38.61596],[-77.084556,38.709068],[-77.040741,38.785745],[-77.040741,38.791222],[-77.002402,38.966484],[-76.887386,39.130793]]]}}, -{"type":"Feature","id":"24035","properties":{"name":"Queen Anne's"},"geometry":{"type":"Polygon","coordinates":[[[-75.846768,39.256762],[-75.75366,39.245808],[-75.748183,39.141746],[-75.748183,39.141746],[-75.95083,38.917192],[-76.071322,38.9391],[-76.197292,38.851469],[-76.158953,39.092454],[-75.846768,39.256762]]]}}, -{"type":"Feature","id":"24037","properties":{"name":"St. Mary's"},"geometry":{"type":"Polygon","coordinates":[[[-76.706647,38.506421],[-76.673786,38.500944],[-76.405416,38.320205],[-76.832617,38.298298],[-76.706647,38.506421]]]}}, -{"type":"Feature","id":"24039","properties":{"name":"Somerset"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-75.62769,38.281867],[-75.611259,38.27639],[-75.622213,37.991589],[-75.671506,37.95325],[-75.863199,38.238051],[-75.62769,38.281867]]],[[[-75.994645,37.95325],[-76.016553,37.95325],[-76.043938,37.95325],[-75.994645,37.95325]]]]}}, -{"type":"Feature","id":"24041","properties":{"name":"Talbot"},"geometry":{"type":"Polygon","coordinates":[[[-76.071322,38.9391],[-75.95083,38.917192],[-75.945353,38.676207],[-76.153476,38.632391],[-76.197292,38.851469],[-76.071322,38.9391]]]}}, -{"type":"Feature","id":"24043","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-78.284006,39.722302],[-78.09779,39.722302],[-77.467942,39.722302],[-77.676066,39.322485],[-77.719881,39.322485],[-77.823943,39.492271],[-78.021113,39.61824],[-78.185421,39.694917],[-78.333299,39.634671],[-78.344253,39.722302],[-78.284006,39.722302]]]}}, -{"type":"Feature","id":"24045","properties":{"name":"Wicomico"},"geometry":{"type":"Polygon","coordinates":[[[-75.813906,38.489991],[-75.69889,38.561191],[-75.342889,38.451652],[-75.611259,38.27639],[-75.62769,38.281867],[-75.863199,38.238051],[-75.923445,38.265436],[-75.813906,38.489991]]]}}, -{"type":"Feature","id":"24047","properties":{"name":"Worcester"},"geometry":{"type":"Polygon","coordinates":[[[-75.342889,38.451652],[-75.047134,38.451652],[-75.244304,38.029928],[-75.397659,38.013497],[-75.622213,37.991589],[-75.611259,38.27639],[-75.342889,38.451652]]]}}, -{"type":"Feature","id":"24510","properties":{"name":"Baltimore"},"geometry":{"type":"Polygon","coordinates":[[[-76.651878,39.371778],[-76.525908,39.218424],[-76.531385,39.20747],[-76.619016,39.234854],[-76.619016,39.234854],[-76.651878,39.371778]]]}}, -{"type":"Feature","id":"25001","properties":{"name":"Barnstable"},"geometry":{"type":"Polygon","coordinates":[[[-70.671059,41.513262],[-70.692967,41.524216],[-70.643674,41.715908],[-70.539613,41.809016],[-69.926195,41.694001],[-70.671059,41.513262]]]}}, -{"type":"Feature","id":"25003","properties":{"name":"Berkshire"},"geometry":{"type":"Polygon","coordinates":[[[-73.267129,42.745573],[-73.020667,42.740096],[-72.976851,42.55388],[-72.998759,42.312895],[-73.053528,42.039048],[-73.486206,42.050002],[-73.49716,42.050002],[-73.35476,42.510065],[-73.267129,42.745573]]]}}, -{"type":"Feature","id":"25005","properties":{"name":"Bristol"},"geometry":{"type":"Polygon","coordinates":[[[-71.08183,42.093817],[-71.08183,42.093817],[-70.840844,41.628277],[-71.120168,41.496831],[-71.196845,41.67757],[-71.22423,41.710431],[-71.317338,41.776155],[-71.383061,41.984279],[-71.08183,42.093817]]]}}, -{"type":"Feature","id":"25009","properties":{"name":"Essex"},"geometry":{"type":"Polygon","coordinates":[[[-70.917521,42.887974],[-70.818936,42.871543],[-70.961337,42.444341],[-71.02706,42.444341],[-71.257092,42.734619],[-71.246138,42.740096],[-70.917521,42.887974]]]}}, -{"type":"Feature","id":"25011","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-73.020667,42.740096],[-72.927559,42.740096],[-72.456542,42.729142],[-72.28128,42.723665],[-72.314141,42.345757],[-72.976851,42.55388],[-73.020667,42.740096]]]}}, -{"type":"Feature","id":"25013","properties":{"name":"Hampden"},"geometry":{"type":"Polygon","coordinates":[[[-72.998759,42.312895],[-72.221033,42.247172],[-72.133402,42.028094],[-72.511311,42.033571],[-73.009713,42.039048],[-73.053528,42.039048],[-72.998759,42.312895],[-72.998759,42.312895]]]}}, -{"type":"Feature","id":"25015","properties":{"name":"Hampshire"},"geometry":{"type":"Polygon","coordinates":[[[-72.976851,42.55388],[-72.314141,42.345757],[-72.221033,42.247172],[-72.998759,42.312895],[-72.998759,42.312895],[-72.976851,42.55388]]]}}, -{"type":"Feature","id":"25017","properties":{"name":"Middlesex"},"geometry":{"type":"Polygon","coordinates":[[[-71.257092,42.734619],[-71.02706,42.444341],[-71.158507,42.329326],[-71.163984,42.301941],[-71.191368,42.280033],[-71.262569,42.329326],[-71.476169,42.154064],[-71.897894,42.712712],[-71.257092,42.734619]]]}}, -{"type":"Feature","id":"25021","properties":{"name":"Norfolk"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-71.109214,42.351234],[-71.163984,42.301941],[-71.158507,42.329326],[-71.109214,42.351234]]],[[[-71.262569,42.329326],[-71.191368,42.280033],[-71.005152,42.307418],[-70.906568,42.269079],[-70.901091,42.269079],[-71.08183,42.093817],[-71.08183,42.093817],[-71.383061,41.984279],[-71.498077,42.01714],[-71.476169,42.154064],[-71.262569,42.329326]]]]}}, -{"type":"Feature","id":"25023","properties":{"name":"Plymouth"},"geometry":{"type":"Polygon","coordinates":[[[-70.901091,42.269079],[-70.906568,42.269079],[-70.824413,42.263602],[-70.780598,42.252649],[-70.539613,41.809016],[-70.643674,41.715908],[-70.840844,41.628277],[-71.08183,42.093817],[-70.901091,42.269079]]]}}, -{"type":"Feature","id":"25025","properties":{"name":"Suffolk"},"geometry":{"type":"Polygon","coordinates":[[[-71.02706,42.444341],[-70.961337,42.444341],[-71.005152,42.307418],[-71.191368,42.280033],[-71.163984,42.301941],[-71.109214,42.351234],[-71.158507,42.329326],[-71.02706,42.444341]]]}}, -{"type":"Feature","id":"25027","properties":{"name":"Worcester"},"geometry":{"type":"Polygon","coordinates":[[[-72.28128,42.723665],[-71.930755,42.712712],[-71.897894,42.712712],[-71.476169,42.154064],[-71.498077,42.01714],[-71.799309,42.006186],[-72.100541,42.028094],[-72.133402,42.028094],[-72.221033,42.247172],[-72.314141,42.345757],[-72.28128,42.723665]]]}}, -{"type":"Feature","id":"26001","properties":{"name":"Alcona"},"geometry":{"type":"Polygon","coordinates":[[[-83.547346,44.859672],[-83.322791,44.859672],[-83.317314,44.509148],[-83.886916,44.509148],[-83.886916,44.854195],[-83.547346,44.859672]]]}}, -{"type":"Feature","id":"26003","properties":{"name":"Alger"},"geometry":{"type":"Polygon","coordinates":[[[-85.864092,46.68897],[-85.864092,46.502754],[-86.001015,46.502754],[-86.614433,46.157707],[-87.118311,46.157707],[-87.118311,46.497277],[-86.696587,46.437031],[-85.864092,46.68897]]]}}, -{"type":"Feature","id":"26005","properties":{"name":"Allegan"},"geometry":{"type":"Polygon","coordinates":[[[-86.044831,42.767481],[-85.781938,42.767481],[-85.546429,42.767481],[-85.540952,42.422434],[-85.765507,42.422434],[-85.776461,42.422434],[-86.274862,42.416957],[-86.209139,42.767481],[-86.044831,42.767481]]]}}, -{"type":"Feature","id":"26007","properties":{"name":"Alpena"},"geometry":{"type":"Polygon","coordinates":[[[-83.4871,45.204719],[-83.388515,45.204719],[-83.322791,44.859672],[-83.547346,44.859672],[-83.886916,44.854195],[-83.881439,45.204719],[-83.4871,45.204719]]]}}, -{"type":"Feature","id":"26009","properties":{"name":"Antrim"},"geometry":{"type":"Polygon","coordinates":[[[-85.321875,45.204719],[-84.856335,45.117088],[-84.845381,44.859672],[-85.250674,44.859672],[-85.332828,44.81038],[-85.42046,44.859672],[-85.442367,44.859672],[-85.387598,45.210196],[-85.321875,45.204719]]]}}, -{"type":"Feature","id":"26011","properties":{"name":"Arenac"},"geometry":{"type":"Polygon","coordinates":[[[-83.569254,44.164101],[-83.563777,44.164101],[-83.908824,43.912162],[-84.105994,43.999793],[-84.16624,43.994316],[-84.16624,44.164101],[-83.886916,44.164101],[-83.569254,44.164101]]]}}, -{"type":"Feature","id":"26013","properties":{"name":"Baraga"},"geometry":{"type":"Polygon","coordinates":[[[-88.043914,46.913525],[-88.115114,46.4206],[-88.679239,46.4206],[-88.449208,46.94091],[-88.043914,46.913525]]]}}, -{"type":"Feature","id":"26015","properties":{"name":"Barry"},"geometry":{"type":"Polygon","coordinates":[[[-85.130182,42.772958],[-85.075412,42.772958],[-85.069935,42.422434],[-85.299967,42.416957],[-85.540952,42.422434],[-85.546429,42.767481],[-85.310921,42.767481],[-85.130182,42.772958]]]}}, -{"type":"Feature","id":"26017","properties":{"name":"Bay"},"geometry":{"type":"Polygon","coordinates":[[[-84.105994,43.999793],[-83.908824,43.912162],[-83.7007,43.594499],[-83.7007,43.479483],[-84.138855,43.567114],[-84.16624,43.567114],[-84.16624,43.82453],[-84.16624,43.994316],[-84.105994,43.999793]]]}}, -{"type":"Feature","id":"26019","properties":{"name":"Benzie"},"geometry":{"type":"Polygon","coordinates":[[[-86.039354,44.777518],[-85.814799,44.772041],[-85.814799,44.514625],[-86.181754,44.520102],[-86.231047,44.520102],[-86.072215,44.777518],[-86.039354,44.777518]]]}}, -{"type":"Feature","id":"26021","properties":{"name":"Berrien"},"geometry":{"type":"Polygon","coordinates":[[[-86.302247,42.241695],[-86.22557,42.07191],[-86.22557,41.759724],[-86.521325,41.759724],[-86.822556,41.759724],[-86.362493,42.241695],[-86.302247,42.241695]]]}}, -{"type":"Feature","id":"26023","properties":{"name":"Branch"},"geometry":{"type":"Polygon","coordinates":[[[-85.053504,42.07191],[-84.82895,42.07191],[-84.823473,41.759724],[-85.195905,41.759724],[-85.29449,41.759724],[-85.29449,42.07191],[-85.053504,42.07191]]]}}, -{"type":"Feature","id":"26025","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-84.883719,42.422434],[-84.719411,42.422434],[-84.708457,42.07191],[-84.82895,42.07191],[-85.053504,42.07191],[-85.29449,42.07191],[-85.299967,42.416957],[-85.069935,42.422434],[-84.883719,42.422434]]]}}, -{"type":"Feature","id":"26027","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-86.22557,42.07191],[-85.765507,42.07191],[-85.792891,41.759724],[-85.990061,41.759724],[-86.061262,41.759724],[-86.22557,41.759724],[-86.22557,42.07191]]]}}, -{"type":"Feature","id":"26029","properties":{"name":"Charlevoix"},"geometry":{"type":"Polygon","coordinates":[[[-85.09732,45.363551],[-84.730365,45.286874],[-84.735842,45.204719],[-84.856335,45.117088],[-85.321875,45.204719],[-85.387598,45.210196],[-85.09732,45.369028],[-85.09732,45.363551]]]}}, -{"type":"Feature","id":"26031","properties":{"name":"Cheboygan"},"geometry":{"type":"Polygon","coordinates":[[[-84.730365,45.779798],[-84.730365,45.785275],[-84.204579,45.626444],[-84.248394,45.199243],[-84.368887,45.199243],[-84.735842,45.204719],[-84.730365,45.286874],[-84.730365,45.779798]]]}}, -{"type":"Feature","id":"26033","properties":{"name":"Chippewa"},"geometry":{"type":"Polygon","coordinates":[[[-84.116948,45.976968],[-85.23972,46.245338],[-85.23972,46.754694],[-85.015166,46.480847],[-84.127902,46.530139],[-84.116948,45.976968]]]}}, -{"type":"Feature","id":"26035","properties":{"name":"Clare"},"geometry":{"type":"Polygon","coordinates":[[[-85.086366,44.164101],[-84.850858,44.158624],[-84.609872,44.158624],[-84.604395,43.813577],[-84.752273,43.813577],[-85.086366,43.813577],[-85.086366,44.164101]]]}}, -{"type":"Feature","id":"26037","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-84.719411,43.118005],[-84.368887,43.118005],[-84.36341,42.778435],[-84.604395,42.767481],[-84.834427,42.772958],[-84.834427,43.118005],[-84.719411,43.118005]]]}}, -{"type":"Feature","id":"26039","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-84.774181,44.859672],[-84.374364,44.854195],[-84.368887,44.509148],[-84.735842,44.509148],[-84.850858,44.509148],[-84.845381,44.859672],[-84.774181,44.859672]]]}}, -{"type":"Feature","id":"26041","properties":{"name":"Delta"},"geometry":{"type":"Polygon","coordinates":[[[-87.118311,46.157707],[-86.614433,46.157707],[-86.461078,45.75789],[-86.784218,45.861952],[-87.266188,45.549767],[-87.37025,45.987922],[-87.118311,46.157707]]]}}, -{"type":"Feature","id":"26043","properties":{"name":"Dickinson"},"geometry":{"type":"Polygon","coordinates":[[[-87.802929,46.245338],[-87.616713,45.987922],[-87.846744,45.725029],[-88.060345,45.779798],[-88.115114,45.922199],[-88.115114,46.245338],[-87.802929,46.245338]]]}}, -{"type":"Feature","id":"26045","properties":{"name":"Eaton"},"geometry":{"type":"Polygon","coordinates":[[[-84.834427,42.772958],[-84.604395,42.767481],[-84.598918,42.422434],[-84.719411,42.422434],[-84.883719,42.422434],[-85.069935,42.422434],[-85.075412,42.772958],[-84.834427,42.772958]]]}}, -{"type":"Feature","id":"26047","properties":{"name":"Emmet"},"geometry":{"type":"Polygon","coordinates":[[[-84.730365,45.785275],[-84.730365,45.779798],[-84.730365,45.286874],[-85.09732,45.363551],[-85.09732,45.369028],[-84.730365,45.785275]]]}}, -{"type":"Feature","id":"26049","properties":{"name":"Genesee"},"geometry":{"type":"Polygon","coordinates":[[[-83.465192,43.222067],[-83.459715,43.222067],[-83.454238,42.882497],[-83.684269,42.783912],[-83.925255,42.778435],[-83.930732,43.134436],[-83.695223,43.222067],[-83.465192,43.222067]]]}}, -{"type":"Feature","id":"26051","properties":{"name":"Gladwin"},"geometry":{"type":"Polygon","coordinates":[[[-84.248394,44.164101],[-84.16624,44.164101],[-84.16624,43.994316],[-84.16624,43.82453],[-84.368887,43.830007],[-84.604395,43.813577],[-84.609872,44.158624],[-84.368887,44.158624],[-84.248394,44.164101]]]}}, -{"type":"Feature","id":"26053","properties":{"name":"Gogebic"},"geometry":{"type":"Polygon","coordinates":[[[-89.889643,46.765647],[-89.741765,46.502754],[-88.991425,46.332969],[-88.991425,46.097461],[-89.927981,46.300108],[-90.415429,46.568478],[-89.889643,46.765647]]]}}, -{"type":"Feature","id":"26055","properties":{"name":"Grand Traverse"},"geometry":{"type":"Polygon","coordinates":[[[-85.42046,44.859672],[-85.332828,44.81038],[-85.332828,44.514625],[-85.694307,44.514625],[-85.814799,44.514625],[-85.814799,44.772041],[-85.639537,44.777518],[-85.442367,44.859672],[-85.42046,44.859672]]]}}, -{"type":"Feature","id":"26057","properties":{"name":"Gratiot"},"geometry":{"type":"Polygon","coordinates":[[[-84.774181,43.468529],[-84.609872,43.468529],[-84.368887,43.468529],[-84.368887,43.128959],[-84.368887,43.118005],[-84.719411,43.118005],[-84.834427,43.118005],[-84.845381,43.468529],[-84.774181,43.468529]]]}}, -{"type":"Feature","id":"26059","properties":{"name":"Hillsdale"},"geometry":{"type":"Polygon","coordinates":[[[-84.36341,42.07191],[-84.357933,41.704955],[-84.401749,41.704955],[-84.807042,41.694001],[-84.823473,41.759724],[-84.82895,42.07191],[-84.708457,42.07191],[-84.36341,42.07191]]]}}, -{"type":"Feature","id":"26061","properties":{"name":"Houghton"},"geometry":{"type":"Polygon","coordinates":[[[-88.383484,47.285957],[-88.23013,47.198326],[-88.449208,46.94091],[-88.679239,46.4206],[-88.712101,46.4206],[-88.991425,46.4206],[-88.931178,47.034018],[-88.514931,47.285957],[-88.383484,47.285957]]]}}, -{"type":"Feature","id":"26063","properties":{"name":"Huron"},"geometry":{"type":"Polygon","coordinates":[[[-82.605312,43.693084],[-82.69842,43.687607],[-83.120145,43.676653],[-83.465192,43.725946],[-83.465192,43.731422],[-82.917498,44.070993],[-82.605312,43.693084]]]}}, -{"type":"Feature","id":"26065","properties":{"name":"Ingham"},"geometry":{"type":"Polygon","coordinates":[[[-84.270302,42.778435],[-84.160763,42.778435],[-84.138855,42.422434],[-84.598918,42.422434],[-84.604395,42.767481],[-84.36341,42.778435],[-84.270302,42.778435]]]}}, -{"type":"Feature","id":"26067","properties":{"name":"Ionia"},"geometry":{"type":"Polygon","coordinates":[[[-85.075412,43.118005],[-84.834427,43.118005],[-84.834427,42.772958],[-85.075412,42.772958],[-85.130182,42.772958],[-85.310921,42.767481],[-85.310921,43.118005],[-85.075412,43.118005]]]}}, -{"type":"Feature","id":"26069","properties":{"name":"Iosco"},"geometry":{"type":"Polygon","coordinates":[[[-83.563777,44.164101],[-83.569254,44.164101],[-83.886916,44.164101],[-83.886916,44.509148],[-83.317314,44.509148],[-83.563777,44.164101]]]}}, -{"type":"Feature","id":"26071","properties":{"name":"Iron"},"geometry":{"type":"Polygon","coordinates":[[[-88.712101,46.4206],[-88.679239,46.4206],[-88.115114,46.4206],[-88.115114,46.245338],[-88.115114,45.922199],[-88.493023,45.993399],[-88.684716,46.015307],[-88.931178,46.075553],[-88.991425,46.097461],[-88.991425,46.332969],[-88.991425,46.4206],[-88.712101,46.4206]]]}}, -{"type":"Feature","id":"26073","properties":{"name":"Isabella"},"geometry":{"type":"Polygon","coordinates":[[[-84.752273,43.813577],[-84.604395,43.813577],[-84.609872,43.468529],[-84.774181,43.468529],[-84.845381,43.468529],[-85.086366,43.468529],[-85.086366,43.813577],[-84.752273,43.813577]]]}}, -{"type":"Feature","id":"26075","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-84.598918,42.422434],[-84.138855,42.422434],[-84.133379,42.422434],[-84.133379,42.07191],[-84.36341,42.07191],[-84.708457,42.07191],[-84.719411,42.422434],[-84.598918,42.422434]]]}}, -{"type":"Feature","id":"26077","properties":{"name":"Kalamazoo"},"geometry":{"type":"Polygon","coordinates":[[[-85.540952,42.422434],[-85.299967,42.416957],[-85.29449,42.07191],[-85.299967,42.07191],[-85.765507,42.07191],[-85.765507,42.422434],[-85.540952,42.422434]]]}}, -{"type":"Feature","id":"26079","properties":{"name":"Kalkaska"},"geometry":{"type":"Polygon","coordinates":[[[-85.250674,44.859672],[-84.845381,44.859672],[-84.850858,44.509148],[-85.332828,44.514625],[-85.332828,44.81038],[-85.250674,44.859672]]]}}, -{"type":"Feature","id":"26081","properties":{"name":"Kent"},"geometry":{"type":"Polygon","coordinates":[[[-85.524521,43.293267],[-85.310921,43.118005],[-85.310921,42.767481],[-85.546429,42.767481],[-85.781938,42.767481],[-85.792891,43.205636],[-85.792891,43.293267],[-85.56286,43.293267],[-85.524521,43.293267]]]}}, -{"type":"Feature","id":"26083","properties":{"name":"Keweenaw"},"geometry":{"type":"Polygon","coordinates":[[[-88.23013,47.198326],[-88.383484,47.285957],[-88.514931,47.285957],[-88.23013,47.198326]]]}}, -{"type":"Feature","id":"26085","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-86.044831,44.169578],[-85.820276,44.164101],[-85.56286,44.164101],[-85.56286,43.813577],[-85.63406,43.813577],[-86.039354,43.813577],[-86.044831,44.169578]]]}}, -{"type":"Feature","id":"26087","properties":{"name":"Lapeer"},"geometry":{"type":"Polygon","coordinates":[[[-83.191345,43.326129],[-83.120145,43.326129],[-82.994175,43.156344],[-82.983221,42.893451],[-83.098237,42.887974],[-83.454238,42.882497],[-83.459715,43.222067],[-83.191345,43.326129]]]}}, -{"type":"Feature","id":"26089","properties":{"name":"Leelanau"},"geometry":{"type":"Polygon","coordinates":[[[-85.639537,44.777518],[-85.814799,44.772041],[-86.039354,44.777518],[-86.072215,44.777518],[-85.617629,45.188289],[-85.639537,44.777518]]]}}, -{"type":"Feature","id":"26091","properties":{"name":"Lenawee"},"geometry":{"type":"Polygon","coordinates":[[[-83.7719,42.082863],[-83.760947,41.721385],[-83.881439,41.721385],[-83.89787,41.721385],[-84.357933,41.704955],[-84.36341,42.07191],[-84.133379,42.07191],[-83.7719,42.082863]]]}}, -{"type":"Feature","id":"26093","properties":{"name":"Livingston"},"geometry":{"type":"Polygon","coordinates":[[[-83.684269,42.783912],[-83.662362,42.433388],[-84.133379,42.422434],[-84.138855,42.422434],[-84.160763,42.778435],[-83.925255,42.778435],[-83.684269,42.783912]]]}}, -{"type":"Feature","id":"26095","properties":{"name":"Luce"},"geometry":{"type":"Polygon","coordinates":[[[-85.23972,46.754694],[-85.23972,46.245338],[-85.36569,46.245338],[-85.864092,46.245338],[-85.864092,46.502754],[-85.864092,46.68897],[-85.23972,46.754694]]]}}, -{"type":"Feature","id":"26097","properties":{"name":"Mackinac"},"geometry":{"type":"Polygon","coordinates":[[[-85.36569,46.245338],[-85.23972,46.245338],[-84.116948,45.976968],[-84.70298,45.850998],[-85.513567,46.097461],[-85.864092,45.966014],[-85.864092,46.245338],[-85.36569,46.245338]]]}}, -{"type":"Feature","id":"26099","properties":{"name":"Macomb"},"geometry":{"type":"Polygon","coordinates":[[[-82.742236,42.898928],[-82.703897,42.685327],[-82.868205,42.449818],[-82.879159,42.449818],[-83.081806,42.449818],[-83.098237,42.887974],[-82.983221,42.893451],[-82.742236,42.898928]]]}}, -{"type":"Feature","id":"26101","properties":{"name":"Manistee"},"geometry":{"type":"Polygon","coordinates":[[[-86.181754,44.520102],[-85.814799,44.514625],[-85.820276,44.164101],[-86.044831,44.169578],[-86.384401,44.180532],[-86.231047,44.520102],[-86.181754,44.520102]]]}}, -{"type":"Feature","id":"26103","properties":{"name":"Marquette"},"geometry":{"type":"Polygon","coordinates":[[[-87.118311,46.497277],[-87.118311,46.157707],[-87.37025,45.987922],[-87.616713,45.987922],[-87.802929,46.245338],[-88.115114,46.245338],[-88.115114,46.4206],[-88.043914,46.913525],[-87.118311,46.497277]]]}}, -{"type":"Feature","id":"26105","properties":{"name":"Mason"},"geometry":{"type":"Polygon","coordinates":[[[-86.384401,44.180532],[-86.044831,44.169578],[-86.039354,43.813577],[-86.433693,43.819054],[-86.384401,44.180532]]]}}, -{"type":"Feature","id":"26107","properties":{"name":"Mecosta"},"geometry":{"type":"Polygon","coordinates":[[[-85.540952,43.813577],[-85.086366,43.813577],[-85.086366,43.468529],[-85.551906,43.468529],[-85.56286,43.468529],[-85.56286,43.813577],[-85.540952,43.813577]]]}}, -{"type":"Feature","id":"26109","properties":{"name":"Menominee"},"geometry":{"type":"Polygon","coordinates":[[[-87.616713,45.987922],[-87.37025,45.987922],[-87.266188,45.549767],[-87.589328,45.095181],[-87.846744,45.725029],[-87.616713,45.987922]]]}}, -{"type":"Feature","id":"26111","properties":{"name":"Midland"},"geometry":{"type":"Polygon","coordinates":[[[-84.368887,43.830007],[-84.16624,43.82453],[-84.16624,43.567114],[-84.368887,43.468529],[-84.609872,43.468529],[-84.604395,43.813577],[-84.368887,43.830007]]]}}, -{"type":"Feature","id":"26113","properties":{"name":"Missaukee"},"geometry":{"type":"Polygon","coordinates":[[[-85.332828,44.514625],[-84.850858,44.509148],[-84.850858,44.158624],[-85.086366,44.164101],[-85.332828,44.164101],[-85.332828,44.514625]]]}}, -{"type":"Feature","id":"26115","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-83.421376,42.093817],[-83.185868,42.033571],[-83.454238,41.732339],[-83.760947,41.721385],[-83.7719,42.082863],[-83.541869,42.082863],[-83.421376,42.093817]]]}}, -{"type":"Feature","id":"26117","properties":{"name":"Montcalm"},"geometry":{"type":"Polygon","coordinates":[[[-85.551906,43.468529],[-85.086366,43.468529],[-84.845381,43.468529],[-84.834427,43.118005],[-85.075412,43.118005],[-85.310921,43.118005],[-85.524521,43.293267],[-85.56286,43.293267],[-85.56286,43.468529],[-85.551906,43.468529]]]}}, -{"type":"Feature","id":"26119","properties":{"name":"Montmorency"},"geometry":{"type":"Polygon","coordinates":[[[-84.199102,45.199243],[-83.881439,45.204719],[-83.886916,44.854195],[-83.952639,44.854195],[-84.374364,44.854195],[-84.368887,45.199243],[-84.248394,45.199243],[-84.199102,45.199243]]]}}, -{"type":"Feature","id":"26121","properties":{"name":"Muskegon"},"geometry":{"type":"Polygon","coordinates":[[[-86.411786,43.474006],[-86.039354,43.468529],[-85.792891,43.293267],[-85.792891,43.205636],[-86.269385,43.118005],[-86.461078,43.474006],[-86.411786,43.474006]]]}}, -{"type":"Feature","id":"26123","properties":{"name":"Newaygo"},"geometry":{"type":"Polygon","coordinates":[[[-85.63406,43.813577],[-85.56286,43.813577],[-85.56286,43.468529],[-85.56286,43.293267],[-85.792891,43.293267],[-86.039354,43.468529],[-86.039354,43.813577],[-85.63406,43.813577]]]}}, -{"type":"Feature","id":"26125","properties":{"name":"Oakland"},"geometry":{"type":"Polygon","coordinates":[[[-83.098237,42.887974],[-83.081806,42.449818],[-83.552823,42.433388],[-83.662362,42.433388],[-83.684269,42.783912],[-83.454238,42.882497],[-83.098237,42.887974]]]}}, -{"type":"Feature","id":"26127","properties":{"name":"Oceana"},"geometry":{"type":"Polygon","coordinates":[[[-86.433693,43.819054],[-86.039354,43.813577],[-86.039354,43.468529],[-86.411786,43.474006],[-86.461078,43.474006],[-86.433693,43.819054]]]}}, -{"type":"Feature","id":"26129","properties":{"name":"Ogemaw"},"geometry":{"type":"Polygon","coordinates":[[[-83.925255,44.509148],[-83.886916,44.509148],[-83.886916,44.164101],[-84.16624,44.164101],[-84.248394,44.164101],[-84.368887,44.158624],[-84.368887,44.509148],[-83.925255,44.509148]]]}}, -{"type":"Feature","id":"26131","properties":{"name":"Ontonagon"},"geometry":{"type":"Polygon","coordinates":[[[-88.931178,47.034018],[-88.991425,46.4206],[-88.991425,46.332969],[-89.741765,46.502754],[-89.889643,46.765647],[-88.931178,47.034018]]]}}, -{"type":"Feature","id":"26133","properties":{"name":"Osceola"},"geometry":{"type":"Polygon","coordinates":[[[-85.486183,44.164101],[-85.332828,44.164101],[-85.086366,44.164101],[-85.086366,43.813577],[-85.540952,43.813577],[-85.56286,43.813577],[-85.56286,44.164101],[-85.486183,44.164101]]]}}, -{"type":"Feature","id":"26135","properties":{"name":"Oscoda"},"geometry":{"type":"Polygon","coordinates":[[[-83.952639,44.854195],[-83.886916,44.854195],[-83.886916,44.509148],[-83.925255,44.509148],[-84.368887,44.509148],[-84.374364,44.854195],[-83.952639,44.854195]]]}}, -{"type":"Feature","id":"26137","properties":{"name":"Otsego"},"geometry":{"type":"Polygon","coordinates":[[[-84.735842,45.204719],[-84.368887,45.199243],[-84.374364,44.854195],[-84.774181,44.859672],[-84.845381,44.859672],[-84.856335,45.117088],[-84.735842,45.204719]]]}}, -{"type":"Feature","id":"26139","properties":{"name":"Ottawa"},"geometry":{"type":"Polygon","coordinates":[[[-85.792891,43.205636],[-85.781938,42.767481],[-86.044831,42.767481],[-86.209139,42.767481],[-86.269385,43.118005],[-85.792891,43.205636]]]}}, -{"type":"Feature","id":"26141","properties":{"name":"Presque Isle"},"geometry":{"type":"Polygon","coordinates":[[[-83.388515,45.204719],[-83.4871,45.204719],[-83.881439,45.204719],[-84.199102,45.199243],[-84.248394,45.199243],[-84.204579,45.626444],[-83.388515,45.204719]]]}}, -{"type":"Feature","id":"26143","properties":{"name":"Roscommon"},"geometry":{"type":"Polygon","coordinates":[[[-84.735842,44.509148],[-84.368887,44.509148],[-84.368887,44.158624],[-84.609872,44.158624],[-84.850858,44.158624],[-84.850858,44.509148],[-84.735842,44.509148]]]}}, -{"type":"Feature","id":"26145","properties":{"name":"Saginaw"},"geometry":{"type":"Polygon","coordinates":[[[-84.138855,43.567114],[-83.7007,43.479483],[-83.695223,43.222067],[-83.930732,43.134436],[-83.941686,43.134436],[-84.368887,43.128959],[-84.368887,43.468529],[-84.16624,43.567114],[-84.138855,43.567114]]]}}, -{"type":"Feature","id":"26147","properties":{"name":"St. Clair"},"geometry":{"type":"Polygon","coordinates":[[[-82.566974,43.167298],[-82.50125,43.167298],[-82.703897,42.685327],[-82.742236,42.898928],[-82.983221,42.893451],[-82.994175,43.156344],[-82.566974,43.167298]]]}}, -{"type":"Feature","id":"26149","properties":{"name":"St. Joseph"},"geometry":{"type":"Polygon","coordinates":[[[-85.299967,42.07191],[-85.29449,42.07191],[-85.29449,41.759724],[-85.371167,41.759724],[-85.661445,41.759724],[-85.792891,41.759724],[-85.765507,42.07191],[-85.299967,42.07191]]]}}, -{"type":"Feature","id":"26151","properties":{"name":"Sanilac"},"geometry":{"type":"Polygon","coordinates":[[[-82.69842,43.687607],[-82.605312,43.693084],[-82.50125,43.167298],[-82.566974,43.167298],[-82.994175,43.156344],[-83.120145,43.326129],[-83.120145,43.676653],[-82.69842,43.687607]]]}}, -{"type":"Feature","id":"26153","properties":{"name":"Schoolcraft"},"geometry":{"type":"Polygon","coordinates":[[[-86.001015,46.502754],[-85.864092,46.502754],[-85.864092,46.245338],[-85.864092,45.966014],[-86.461078,45.75789],[-86.614433,46.157707],[-86.001015,46.502754]]]}}, -{"type":"Feature","id":"26155","properties":{"name":"Shiawassee"},"geometry":{"type":"Polygon","coordinates":[[[-83.941686,43.134436],[-83.930732,43.134436],[-83.925255,42.778435],[-84.160763,42.778435],[-84.270302,42.778435],[-84.36341,42.778435],[-84.368887,43.118005],[-84.368887,43.128959],[-83.941686,43.134436]]]}}, -{"type":"Feature","id":"26157","properties":{"name":"Tuscola"},"geometry":{"type":"Polygon","coordinates":[[[-83.465192,43.725946],[-83.120145,43.676653],[-83.120145,43.326129],[-83.191345,43.326129],[-83.459715,43.222067],[-83.465192,43.222067],[-83.695223,43.222067],[-83.7007,43.479483],[-83.7007,43.594499],[-83.465192,43.731422],[-83.465192,43.725946]]]}}, -{"type":"Feature","id":"26159","properties":{"name":"Van Buren"},"geometry":{"type":"Polygon","coordinates":[[[-85.776461,42.422434],[-85.765507,42.422434],[-85.765507,42.07191],[-86.22557,42.07191],[-86.302247,42.241695],[-86.362493,42.241695],[-86.274862,42.416957],[-85.776461,42.422434]]]}}, -{"type":"Feature","id":"26161","properties":{"name":"Washtenaw"},"geometry":{"type":"Polygon","coordinates":[[[-83.552823,42.433388],[-83.541869,42.082863],[-83.7719,42.082863],[-84.133379,42.07191],[-84.133379,42.422434],[-83.662362,42.433388],[-83.552823,42.433388]]]}}, -{"type":"Feature","id":"26163","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-82.879159,42.449818],[-82.868205,42.449818],[-83.185868,42.033571],[-83.421376,42.093817],[-83.541869,42.082863],[-83.552823,42.433388],[-83.081806,42.449818],[-82.879159,42.449818]]]}}, -{"type":"Feature","id":"26165","properties":{"name":"Wexford"},"geometry":{"type":"Polygon","coordinates":[[[-85.694307,44.514625],[-85.332828,44.514625],[-85.332828,44.164101],[-85.486183,44.164101],[-85.56286,44.164101],[-85.820276,44.164101],[-85.814799,44.514625],[-85.694307,44.514625]]]}}, -{"type":"Feature","id":"27001","properties":{"name":"Aitkin"},"geometry":{"type":"Polygon","coordinates":[[[-93.712547,47.028541],[-93.055314,47.028541],[-93.060791,46.765647],[-93.055314,46.4206],[-93.055314,46.157707],[-93.307254,46.157707],[-93.433223,46.15223],[-93.553716,46.245338],[-93.794701,46.245338],[-93.778271,46.803986],[-93.772794,47.028541],[-93.712547,47.028541]]]}}, -{"type":"Feature","id":"27003","properties":{"name":"Anoka"},"geometry":{"type":"Polygon","coordinates":[[[-93.159376,45.412843],[-93.016976,45.412843],[-93.016976,45.297827],[-93.022453,45.122565],[-93.230576,45.122565],[-93.2251,45.034934],[-93.5099,45.243058],[-93.5099,45.412843],[-93.159376,45.412843]]]}}, -{"type":"Feature","id":"27005","properties":{"name":"Becker"},"geometry":{"type":"Polygon","coordinates":[[[-95.169413,47.15451],[-95.163936,46.803986],[-95.163936,46.716355],[-96.17717,46.716355],[-96.193601,47.149033],[-96.067632,47.149033],[-95.552799,47.149033],[-95.169413,47.15451]]]}}, -{"type":"Feature","id":"27007","properties":{"name":"Beltrami"},"geometry":{"type":"Polygon","coordinates":[[[-95.344675,48.540176],[-94.430026,48.364914],[-94.419073,47.844605],[-94.413596,47.444788],[-94.671012,47.411926],[-95.185844,47.411926],[-95.22966,48.019867],[-95.580184,48.019867],[-95.591138,48.173221],[-95.602092,48.540176],[-95.344675,48.540176]]]}}, -{"type":"Feature","id":"27009","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-94.008302,45.823614],[-93.76184,45.823614],[-93.76184,45.560721],[-94.150702,45.560721],[-94.271195,45.774321],[-94.008302,45.823614]]]}}, -{"type":"Feature","id":"27011","properties":{"name":"Big Stone"},"geometry":{"type":"Polygon","coordinates":[[[-96.828926,45.588105],[-96.253848,45.588105],[-96.116924,45.412843],[-96.10597,45.177335],[-96.368863,45.259489],[-96.451017,45.270443],[-96.451017,45.297827],[-96.456494,45.303304],[-96.472925,45.325212],[-96.834403,45.588105],[-96.828926,45.588105]]]}}, -{"type":"Feature","id":"27013","properties":{"name":"Blue Earth"},"geometry":{"type":"Polygon","coordinates":[[[-94.331441,44.251732],[-94.013779,44.240778],[-93.767317,44.196962],[-93.767317,43.846438],[-93.893286,43.846438],[-94.249287,43.846438],[-94.36978,43.846438],[-94.36978,44.109331],[-94.36978,44.262686],[-94.331441,44.251732]]]}}, -{"type":"Feature","id":"27015","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-94.851751,44.498194],[-94.780551,44.454379],[-94.36978,44.262686],[-94.36978,44.109331],[-94.490273,44.109331],[-94.857228,44.109331],[-95.109167,44.196962],[-94.868182,44.498194],[-94.851751,44.498194]]]}}, -{"type":"Feature","id":"27017","properties":{"name":"Carlton"},"geometry":{"type":"Polygon","coordinates":[[[-92.49119,46.765647],[-92.29402,46.661586],[-92.29402,46.415123],[-92.962206,46.4206],[-93.055314,46.4206],[-93.060791,46.765647],[-92.49119,46.765647]]]}}, -{"type":"Feature","id":"27019","properties":{"name":"Carver"},"geometry":{"type":"Polygon","coordinates":[[[-94.013779,44.980165],[-93.767317,44.980165],[-93.520854,44.804903],[-93.767317,44.640595],[-94.008302,44.717272],[-94.013779,44.980165]]]}}, -{"type":"Feature","id":"27021","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-94.052118,47.428357],[-93.772794,47.028541],[-93.778271,46.803986],[-94.282149,46.803986],[-94.342395,46.2782],[-94.654581,46.3494],[-94.731258,46.371308],[-94.786028,46.803986],[-94.671012,47.411926],[-94.413596,47.444788],[-94.052118,47.428357]]]}}, -{"type":"Feature","id":"27023","properties":{"name":"Chippewa"},"geometry":{"type":"Polygon","coordinates":[[[-95.574707,45.14995],[-95.246091,45.14995],[-95.246091,44.892534],[-95.481599,44.75561],[-95.733538,44.930872],[-95.739015,44.936349],[-96.03477,45.14995],[-95.574707,45.14995]]]}}, -{"type":"Feature","id":"27025","properties":{"name":"Chisago"},"geometry":{"type":"Polygon","coordinates":[[[-93.066268,45.730506],[-92.841714,45.730506],[-92.885529,45.642875],[-92.743129,45.297827],[-93.016976,45.297827],[-93.016976,45.412843],[-93.142945,45.730506],[-93.066268,45.730506]]]}}, -{"type":"Feature","id":"27027","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-96.582464,47.149033],[-96.193601,47.149033],[-96.17717,46.716355],[-96.281232,46.628724],[-96.790588,46.628724],[-96.790588,46.628724],[-96.828926,47.149033],[-96.582464,47.149033]]]}}, -{"type":"Feature","id":"27029","properties":{"name":"Clearwater"},"geometry":{"type":"Polygon","coordinates":[[[-95.580184,48.019867],[-95.22966,48.019867],[-95.185844,47.411926],[-95.169413,47.15451],[-95.552799,47.149033],[-95.552799,47.499557],[-95.580184,47.932236],[-95.580184,48.019867]]]}}, -{"type":"Feature","id":"27031","properties":{"name":"Cook"},"geometry":{"type":"Polygon","coordinates":[[[-91.023369,47.466696],[-91.034323,48.189652],[-89.582934,47.997959],[-91.023369,47.466696]]]}}, -{"type":"Feature","id":"27033","properties":{"name":"Cottonwood"},"geometry":{"type":"Polygon","coordinates":[[[-95.459691,44.196962],[-95.109167,44.196962],[-94.857228,44.109331],[-94.857228,43.846438],[-95.114644,43.846438],[-95.454214,43.846438],[-95.465168,43.846438],[-95.459691,44.196962]]]}}, -{"type":"Feature","id":"27035","properties":{"name":"Crow Wing"},"geometry":{"type":"Polygon","coordinates":[[[-94.282149,46.803986],[-93.778271,46.803986],[-93.794701,46.245338],[-93.811132,46.157707],[-94.342395,46.2782],[-94.282149,46.803986]]]}}, -{"type":"Feature","id":"27037","properties":{"name":"Dakota"},"geometry":{"type":"Polygon","coordinates":[[[-93.088176,44.919919],[-93.016976,44.892534],[-92.803375,44.744656],[-92.732175,44.711795],[-93.038884,44.470809],[-93.279869,44.54201],[-93.329161,44.788472],[-93.175807,44.887057],[-93.088176,44.919919]]]}}, -{"type":"Feature","id":"27039","properties":{"name":"Dodge"},"geometry":{"type":"Polygon","coordinates":[[[-92.918391,44.196962],[-92.677405,44.196962],[-92.688359,43.846438],[-92.880052,43.846438],[-93.04436,43.846438],[-93.04436,44.196962],[-93.038884,44.196962],[-92.918391,44.196962]]]}}, -{"type":"Feature","id":"27041","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-95.393968,46.108415],[-95.147506,46.108415],[-95.142029,45.774321],[-95.142029,45.75789],[-95.42683,45.75789],[-95.760923,45.75789],[-95.771877,46.108415],[-95.393968,46.108415]]]}}, -{"type":"Feature","id":"27043","properties":{"name":"Faribault"},"geometry":{"type":"Polygon","coordinates":[[[-93.893286,43.846438],[-93.767317,43.846438],[-93.646824,43.846438],[-93.646824,43.501391],[-93.969963,43.501391],[-94.249287,43.501391],[-94.249287,43.846438],[-93.893286,43.846438]]]}}, -{"type":"Feature","id":"27045","properties":{"name":"Fillmore"},"geometry":{"type":"Polygon","coordinates":[[[-92.381651,43.846438],[-92.080419,43.846438],[-91.729895,43.846438],[-91.729895,43.501391],[-91.850387,43.501391],[-92.080419,43.501391],[-92.447374,43.501391],[-92.447374,43.835484],[-92.381651,43.846438]]]}}, -{"type":"Feature","id":"27047","properties":{"name":"Freeborn"},"geometry":{"type":"Polygon","coordinates":[[[-93.164853,43.846438],[-93.049837,43.846438],[-93.049837,43.501391],[-93.498947,43.501391],[-93.646824,43.501391],[-93.646824,43.846438],[-93.405839,43.846438],[-93.164853,43.846438]]]}}, -{"type":"Feature","id":"27049","properties":{"name":"Goodhue"},"geometry":{"type":"Polygon","coordinates":[[[-92.732175,44.711795],[-92.315927,44.54201],[-92.244727,44.454379],[-92.430943,44.454379],[-92.551436,44.196962],[-92.666452,44.196962],[-92.677405,44.196962],[-92.918391,44.196962],[-93.038884,44.196962],[-93.038884,44.470809],[-92.732175,44.711795]]]}}, -{"type":"Feature","id":"27051","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-96.264801,46.108415],[-95.771877,46.108415],[-95.760923,45.75789],[-96.253848,45.75789],[-96.264801,46.020784],[-96.264801,46.108415]]]}}, -{"type":"Feature","id":"27053","properties":{"name":"Hennepin"},"geometry":{"type":"Polygon","coordinates":[[[-93.520854,45.248535],[-93.5099,45.243058],[-93.2251,45.034934],[-93.175807,44.887057],[-93.329161,44.788472],[-93.433223,44.81038],[-93.520854,44.804903],[-93.767317,44.980165],[-93.520854,45.248535]]]}}, -{"type":"Feature","id":"27055","properties":{"name":"Houston"},"geometry":{"type":"Polygon","coordinates":[[[-91.373894,43.846438],[-91.286263,43.846438],[-91.258878,43.725946],[-91.215062,43.501391],[-91.368417,43.501391],[-91.609402,43.501391],[-91.729895,43.501391],[-91.729895,43.846438],[-91.373894,43.846438]]]}}, -{"type":"Feature","id":"27057","properties":{"name":"Hubbard"},"geometry":{"type":"Polygon","coordinates":[[[-95.185844,47.411926],[-94.671012,47.411926],[-94.786028,46.803986],[-95.037967,46.803986],[-95.163936,46.803986],[-95.169413,47.15451],[-95.185844,47.411926]]]}}, -{"type":"Feature","id":"27059","properties":{"name":"Isanti"},"geometry":{"type":"Polygon","coordinates":[[[-93.498947,45.735983],[-93.142945,45.730506],[-93.016976,45.412843],[-93.159376,45.412843],[-93.5099,45.412843],[-93.5099,45.560721],[-93.515377,45.735983],[-93.498947,45.735983]]]}}, -{"type":"Feature","id":"27061","properties":{"name":"Itasca"},"geometry":{"type":"Polygon","coordinates":[[[-93.597531,47.899374],[-93.082699,47.893897],[-93.055314,47.028541],[-93.712547,47.028541],[-93.772794,47.028541],[-94.052118,47.428357],[-94.413596,47.444788],[-94.419073,47.844605],[-93.597531,47.899374]]]}}, -{"type":"Feature","id":"27063","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-95.114644,43.846438],[-94.857228,43.846438],[-94.851751,43.846438],[-94.851751,43.501391],[-94.917474,43.501391],[-95.092736,43.501391],[-95.388491,43.501391],[-95.454214,43.501391],[-95.454214,43.846438],[-95.114644,43.846438]]]}}, -{"type":"Feature","id":"27065","properties":{"name":"Kanabec"},"geometry":{"type":"Polygon","coordinates":[[[-93.307254,46.157707],[-93.055314,46.157707],[-93.142945,45.730506],[-93.498947,45.735983],[-93.515377,45.735983],[-93.433223,46.15223],[-93.307254,46.157707]]]}}, -{"type":"Feature","id":"27067","properties":{"name":"Kandiyohi"},"geometry":{"type":"Polygon","coordinates":[[[-94.884612,45.412843],[-94.76412,45.325212],[-94.758643,44.892534],[-95.246091,44.892534],[-95.246091,45.14995],[-95.257044,45.412843],[-95.131075,45.412843],[-94.884612,45.412843]]]}}, -{"type":"Feature","id":"27069","properties":{"name":"Kittson"},"geometry":{"type":"Polygon","coordinates":[[[-96.407202,49.000239],[-96.385294,48.545653],[-97.16302,48.545653],[-97.228743,49.000239],[-96.407202,49.000239]]]}}, -{"type":"Feature","id":"27071","properties":{"name":"Koochiching"},"geometry":{"type":"Polygon","coordinates":[[[-93.088176,48.627807],[-93.088176,48.55113],[-93.082699,47.893897],[-93.597531,47.899374],[-94.419073,47.844605],[-94.430026,48.364914],[-94.430026,48.699007],[-93.794701,48.518268],[-93.088176,48.627807]]]}}, -{"type":"Feature","id":"27073","properties":{"name":"Lac qui Parle"},"geometry":{"type":"Polygon","coordinates":[[[-96.368863,45.259489],[-96.10597,45.177335],[-96.03477,45.14995],[-95.739015,44.936349],[-96.451017,44.804903],[-96.451017,44.980165],[-96.451017,45.270443],[-96.368863,45.259489]]]}}, -{"type":"Feature","id":"27075","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-91.801095,47.866512],[-91.795618,48.200606],[-91.034323,48.189652],[-91.023369,47.466696],[-91.795618,46.94091],[-91.801095,47.866512]]]}}, -{"type":"Feature","id":"27077","properties":{"name":"Lake of the Woods"},"geometry":{"type":"Polygon","coordinates":[[[-94.430026,48.699007],[-94.430026,48.364914],[-95.344675,48.540176],[-95.322768,49.000239],[-94.824366,49.295994],[-94.430026,48.699007]]]}}, -{"type":"Feature","id":"27079","properties":{"name":"Le Sueur"},"geometry":{"type":"Polygon","coordinates":[[[-93.701593,44.54201],[-93.526331,44.54201],[-93.526331,44.196962],[-93.679686,44.196962],[-93.767317,44.196962],[-94.013779,44.240778],[-93.931625,44.454379],[-93.909717,44.54201],[-93.701593,44.54201]]]}}, -{"type":"Feature","id":"27081","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-96.44554,44.629641],[-96.095016,44.629641],[-96.078585,44.196962],[-96.242894,44.196962],[-96.451017,44.196962],[-96.451017,44.54201],[-96.451017,44.629641],[-96.44554,44.629641]]]}}, -{"type":"Feature","id":"27083","properties":{"name":"Lyon"},"geometry":{"type":"Polygon","coordinates":[[[-95.936185,44.629641],[-95.596615,44.54201],[-95.591138,44.196962],[-96.012862,44.196962],[-96.062155,44.196962],[-96.078585,44.196962],[-96.095016,44.629641],[-95.936185,44.629641]]]}}, -{"type":"Feature","id":"27085","properties":{"name":"McLeod"},"geometry":{"type":"Polygon","coordinates":[[[-94.254764,44.980165],[-94.013779,44.980165],[-94.008302,44.717272],[-94.134272,44.717272],[-94.49575,44.717272],[-94.49575,44.892534],[-94.501227,44.892534],[-94.254764,44.980165]]]}}, -{"type":"Feature","id":"27087","properties":{"name":"Mahnomen"},"geometry":{"type":"Polygon","coordinates":[[[-95.552799,47.149033],[-96.067632,47.149033],[-96.067632,47.499557],[-95.552799,47.499557],[-95.552799,47.149033]]]}}, -{"type":"Feature","id":"27089","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-96.259324,48.545653],[-95.602092,48.540176],[-95.591138,48.173221],[-96.50031,48.173221],[-97.020619,48.173221],[-97.146589,48.173221],[-97.141112,48.195129],[-97.16302,48.540176],[-97.16302,48.545653],[-96.385294,48.545653],[-96.259324,48.545653]]]}}, -{"type":"Feature","id":"27091","properties":{"name":"Martin"},"geometry":{"type":"Polygon","coordinates":[[[-94.616242,43.846438],[-94.36978,43.846438],[-94.249287,43.846438],[-94.249287,43.501391],[-94.44098,43.501391],[-94.676489,43.501391],[-94.851751,43.501391],[-94.851751,43.846438],[-94.616242,43.846438]]]}}, -{"type":"Feature","id":"27093","properties":{"name":"Meeker"},"geometry":{"type":"Polygon","coordinates":[[[-94.534088,45.325212],[-94.260241,45.281397],[-94.254764,44.980165],[-94.501227,44.892534],[-94.758643,44.892534],[-94.76412,45.325212],[-94.534088,45.325212]]]}}, -{"type":"Feature","id":"27095","properties":{"name":"Mille Lacs"},"geometry":{"type":"Polygon","coordinates":[[[-93.553716,46.245338],[-93.433223,46.15223],[-93.515377,45.735983],[-93.5099,45.560721],[-93.652301,45.560721],[-93.76184,45.560721],[-93.76184,45.823614],[-93.811132,46.157707],[-93.794701,46.245338],[-93.553716,46.245338]]]}}, -{"type":"Feature","id":"27097","properties":{"name":"Morrison"},"geometry":{"type":"Polygon","coordinates":[[[-94.654581,46.3494],[-94.342395,46.2782],[-93.811132,46.157707],[-93.76184,45.823614],[-94.008302,45.823614],[-94.271195,45.774321],[-94.451934,45.774321],[-94.643627,45.774321],[-94.654581,46.3494]]]}}, -{"type":"Feature","id":"27099","properties":{"name":"Mower"},"geometry":{"type":"Polygon","coordinates":[[[-92.880052,43.846438],[-92.688359,43.846438],[-92.447374,43.835484],[-92.447374,43.501391],[-92.551436,43.501391],[-93.022453,43.501391],[-93.049837,43.501391],[-93.049837,43.846438],[-93.04436,43.846438],[-92.880052,43.846438]]]}}, -{"type":"Feature","id":"27101","properties":{"name":"Murray"},"geometry":{"type":"Polygon","coordinates":[[[-96.012862,44.196962],[-95.591138,44.196962],[-95.459691,44.196962],[-95.465168,43.846438],[-96.051201,43.846438],[-96.062155,43.846438],[-96.062155,44.196962],[-96.012862,44.196962]]]}}, -{"type":"Feature","id":"27103","properties":{"name":"Nicollet"},"geometry":{"type":"Polygon","coordinates":[[[-94.112364,44.454379],[-93.931625,44.454379],[-94.013779,44.240778],[-94.331441,44.251732],[-94.36978,44.262686],[-94.780551,44.454379],[-94.621719,44.454379],[-94.112364,44.454379]]]}}, -{"type":"Feature","id":"27105","properties":{"name":"Nobles"},"geometry":{"type":"Polygon","coordinates":[[[-96.051201,43.846438],[-95.465168,43.846438],[-95.454214,43.846438],[-95.454214,43.501391],[-95.859508,43.501391],[-96.051201,43.501391],[-96.051201,43.846438]]]}}, -{"type":"Feature","id":"27107","properties":{"name":"Norman"},"geometry":{"type":"Polygon","coordinates":[[[-96.23194,47.499557],[-96.067632,47.499557],[-96.067632,47.149033],[-96.193601,47.149033],[-96.582464,47.149033],[-96.828926,47.149033],[-96.834403,47.236664],[-96.850834,47.499557],[-96.23194,47.499557]]]}}, -{"type":"Feature","id":"27109","properties":{"name":"Olmsted"},"geometry":{"type":"Polygon","coordinates":[[[-92.666452,44.196962],[-92.551436,44.196962],[-92.080419,44.109331],[-92.080419,43.846438],[-92.381651,43.846438],[-92.447374,43.835484],[-92.688359,43.846438],[-92.677405,44.196962],[-92.666452,44.196962]]]}}, -{"type":"Feature","id":"27111","properties":{"name":"Otter Tail"},"geometry":{"type":"Polygon","coordinates":[[[-96.17717,46.716355],[-95.163936,46.716355],[-95.152983,46.371308],[-95.147506,46.108415],[-95.393968,46.108415],[-95.771877,46.108415],[-96.264801,46.108415],[-96.281232,46.628724],[-96.17717,46.716355]]]}}, -{"type":"Feature","id":"27113","properties":{"name":"Pennington"},"geometry":{"type":"Polygon","coordinates":[[[-96.50031,48.173221],[-95.591138,48.173221],[-95.580184,48.019867],[-95.580184,47.932236],[-95.71163,47.937713],[-95.8376,47.965097],[-96.483879,47.965097],[-96.50031,48.173221]]]}}, -{"type":"Feature","id":"27115","properties":{"name":"Pine"},"geometry":{"type":"Polygon","coordinates":[[[-92.962206,46.4206],[-92.29402,46.415123],[-92.29402,46.157707],[-92.841714,45.730506],[-93.066268,45.730506],[-93.142945,45.730506],[-93.055314,46.157707],[-93.055314,46.4206],[-92.962206,46.4206]]]}}, -{"type":"Feature","id":"27117","properties":{"name":"Pipestone"},"geometry":{"type":"Polygon","coordinates":[[[-96.242894,44.196962],[-96.078585,44.196962],[-96.062155,44.196962],[-96.062155,43.846438],[-96.451017,43.851915],[-96.451017,44.196962],[-96.242894,44.196962]]]}}, -{"type":"Feature","id":"27119","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-97.020619,48.173221],[-96.50031,48.173221],[-96.483879,47.965097],[-96.352432,47.762451],[-95.71163,47.937713],[-95.580184,47.932236],[-95.552799,47.499557],[-96.067632,47.499557],[-96.23194,47.499557],[-96.850834,47.499557],[-96.889173,47.67482],[-97.146589,48.173221],[-97.020619,48.173221]]]}}, -{"type":"Feature","id":"27121","properties":{"name":"Pope"},"geometry":{"type":"Polygon","coordinates":[[[-95.42683,45.75789],[-95.142029,45.75789],[-95.131075,45.412843],[-95.257044,45.412843],[-95.749969,45.412843],[-95.760923,45.75789],[-95.42683,45.75789]]]}}, -{"type":"Feature","id":"27123","properties":{"name":"Ramsey"},"geometry":{"type":"Polygon","coordinates":[[[-93.230576,45.122565],[-93.022453,45.122565],[-93.016976,44.892534],[-93.088176,44.919919],[-93.175807,44.887057],[-93.2251,45.034934],[-93.230576,45.122565]]]}}, -{"type":"Feature","id":"27125","properties":{"name":"Red Lake"},"geometry":{"type":"Polygon","coordinates":[[[-95.8376,47.965097],[-95.71163,47.937713],[-96.352432,47.762451],[-96.483879,47.965097],[-95.8376,47.965097]]]}}, -{"type":"Feature","id":"27127","properties":{"name":"Redwood"},"geometry":{"type":"Polygon","coordinates":[[[-95.295383,44.662502],[-94.868182,44.498194],[-95.109167,44.196962],[-95.459691,44.196962],[-95.591138,44.196962],[-95.596615,44.54201],[-95.361106,44.700841],[-95.295383,44.662502]]]}}, -{"type":"Feature","id":"27129","properties":{"name":"Renville"},"geometry":{"type":"Polygon","coordinates":[[[-94.49575,44.892534],[-94.49575,44.717272],[-94.621719,44.454379],[-94.780551,44.454379],[-94.851751,44.498194],[-94.868182,44.498194],[-95.295383,44.662502],[-95.361106,44.700841],[-95.481599,44.75561],[-95.246091,44.892534],[-94.758643,44.892534],[-94.501227,44.892534],[-94.49575,44.892534]]]}}, -{"type":"Feature","id":"27131","properties":{"name":"Rice"},"geometry":{"type":"Polygon","coordinates":[[[-93.301777,44.54201],[-93.279869,44.54201],[-93.038884,44.470809],[-93.038884,44.196962],[-93.04436,44.196962],[-93.164853,44.196962],[-93.405839,44.196962],[-93.526331,44.196962],[-93.526331,44.54201],[-93.301777,44.54201]]]}}, -{"type":"Feature","id":"27133","properties":{"name":"Rock"},"geometry":{"type":"Polygon","coordinates":[[[-96.451017,43.851915],[-96.062155,43.846438],[-96.051201,43.846438],[-96.051201,43.501391],[-96.451017,43.501391],[-96.451017,43.851915]]]}}, -{"type":"Feature","id":"27135","properties":{"name":"Roseau"},"geometry":{"type":"Polygon","coordinates":[[[-95.322768,49.000239],[-95.344675,48.540176],[-95.602092,48.540176],[-96.259324,48.545653],[-96.385294,48.545653],[-96.407202,49.000239],[-95.322768,49.000239]]]}}, -{"type":"Feature","id":"27137","properties":{"name":"St. Louis"},"geometry":{"type":"Polygon","coordinates":[[[-93.088176,48.55113],[-93.088176,48.627807],[-92.370697,48.222514],[-91.795618,48.200606],[-91.801095,47.866512],[-91.795618,46.94091],[-92.014696,46.705401],[-92.29402,46.661586],[-92.49119,46.765647],[-93.060791,46.765647],[-93.055314,47.028541],[-93.082699,47.893897],[-93.088176,48.55113]]]}}, -{"type":"Feature","id":"27139","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-93.433223,44.81038],[-93.329161,44.788472],[-93.279869,44.54201],[-93.301777,44.54201],[-93.526331,44.54201],[-93.701593,44.54201],[-93.909717,44.54201],[-93.767317,44.640595],[-93.520854,44.804903],[-93.433223,44.81038]]]}}, -{"type":"Feature","id":"27141","properties":{"name":"Sherburne"},"geometry":{"type":"Polygon","coordinates":[[[-93.652301,45.560721],[-93.5099,45.560721],[-93.5099,45.412843],[-93.5099,45.243058],[-93.520854,45.248535],[-94.046641,45.423797],[-94.150702,45.560721],[-93.76184,45.560721],[-93.652301,45.560721]]]}}, -{"type":"Feature","id":"27143","properties":{"name":"Sibley"},"geometry":{"type":"Polygon","coordinates":[[[-94.134272,44.717272],[-94.008302,44.717272],[-93.767317,44.640595],[-93.909717,44.54201],[-93.931625,44.454379],[-94.112364,44.454379],[-94.621719,44.454379],[-94.49575,44.717272],[-94.134272,44.717272]]]}}, -{"type":"Feature","id":"27145","properties":{"name":"Stearns"},"geometry":{"type":"Polygon","coordinates":[[[-94.451934,45.774321],[-94.271195,45.774321],[-94.150702,45.560721],[-94.046641,45.423797],[-94.052118,45.423797],[-94.260241,45.281397],[-94.534088,45.325212],[-94.76412,45.325212],[-94.884612,45.412843],[-95.131075,45.412843],[-95.142029,45.75789],[-95.142029,45.774321],[-94.643627,45.774321],[-94.451934,45.774321]]]}}, -{"type":"Feature","id":"27147","properties":{"name":"Steele"},"geometry":{"type":"Polygon","coordinates":[[[-93.164853,44.196962],[-93.04436,44.196962],[-93.04436,43.846438],[-93.049837,43.846438],[-93.164853,43.846438],[-93.405839,43.846438],[-93.405839,44.196962],[-93.164853,44.196962]]]}}, -{"type":"Feature","id":"27149","properties":{"name":"Stevens"},"geometry":{"type":"Polygon","coordinates":[[[-96.253848,45.75789],[-95.760923,45.75789],[-95.749969,45.412843],[-95.974524,45.412843],[-96.116924,45.412843],[-96.253848,45.588105],[-96.253848,45.75789]]]}}, -{"type":"Feature","id":"27151","properties":{"name":"Swift"},"geometry":{"type":"Polygon","coordinates":[[[-95.974524,45.412843],[-95.749969,45.412843],[-95.257044,45.412843],[-95.246091,45.14995],[-95.574707,45.14995],[-96.03477,45.14995],[-96.10597,45.177335],[-96.116924,45.412843],[-95.974524,45.412843]]]}}, -{"type":"Feature","id":"27153","properties":{"name":"Todd"},"geometry":{"type":"Polygon","coordinates":[[[-95.152983,46.371308],[-94.731258,46.371308],[-94.654581,46.3494],[-94.643627,45.774321],[-95.142029,45.774321],[-95.147506,46.108415],[-95.152983,46.371308]]]}}, -{"type":"Feature","id":"27155","properties":{"name":"Traverse"},"geometry":{"type":"Polygon","coordinates":[[[-96.390771,46.020784],[-96.264801,46.020784],[-96.253848,45.75789],[-96.253848,45.588105],[-96.828926,45.588105],[-96.834403,45.588105],[-96.560556,45.933153],[-96.576987,46.020784],[-96.390771,46.020784]]]}}, -{"type":"Feature","id":"27157","properties":{"name":"Wabasha"},"geometry":{"type":"Polygon","coordinates":[[[-92.430943,44.454379],[-92.244727,44.454379],[-92.085896,44.405086],[-91.855864,44.191485],[-92.069465,44.191485],[-92.080419,44.109331],[-92.551436,44.196962],[-92.430943,44.454379]]]}}, -{"type":"Feature","id":"27159","properties":{"name":"Wadena"},"geometry":{"type":"Polygon","coordinates":[[[-95.037967,46.803986],[-94.786028,46.803986],[-94.731258,46.371308],[-95.152983,46.371308],[-95.163936,46.716355],[-95.163936,46.803986],[-95.037967,46.803986]]]}}, -{"type":"Feature","id":"27161","properties":{"name":"Waseca"},"geometry":{"type":"Polygon","coordinates":[[[-93.679686,44.196962],[-93.526331,44.196962],[-93.405839,44.196962],[-93.405839,43.846438],[-93.646824,43.846438],[-93.767317,43.846438],[-93.767317,44.196962],[-93.679686,44.196962]]]}}, -{"type":"Feature","id":"27163","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-93.016976,45.297827],[-92.743129,45.297827],[-92.75956,45.210196],[-92.770513,44.859672],[-92.803375,44.744656],[-93.016976,44.892534],[-93.022453,45.122565],[-93.016976,45.297827]]]}}, -{"type":"Feature","id":"27165","properties":{"name":"Watonwan"},"geometry":{"type":"Polygon","coordinates":[[[-94.490273,44.109331],[-94.36978,44.109331],[-94.36978,43.846438],[-94.616242,43.846438],[-94.851751,43.846438],[-94.857228,43.846438],[-94.857228,44.109331],[-94.490273,44.109331]]]}}, -{"type":"Feature","id":"27167","properties":{"name":"Wilkin"},"geometry":{"type":"Polygon","coordinates":[[[-96.281232,46.628724],[-96.264801,46.108415],[-96.264801,46.020784],[-96.390771,46.020784],[-96.576987,46.020784],[-96.790588,46.628724],[-96.281232,46.628724]]]}}, -{"type":"Feature","id":"27169","properties":{"name":"Winona"},"geometry":{"type":"Polygon","coordinates":[[[-92.069465,44.191485],[-91.855864,44.191485],[-91.56011,44.027177],[-91.423186,43.983362],[-91.286263,43.846438],[-91.373894,43.846438],[-91.729895,43.846438],[-92.080419,43.846438],[-92.080419,44.109331],[-92.069465,44.191485]]]}}, -{"type":"Feature","id":"27171","properties":{"name":"Wright"},"geometry":{"type":"Polygon","coordinates":[[[-94.052118,45.423797],[-94.046641,45.423797],[-93.520854,45.248535],[-93.767317,44.980165],[-94.013779,44.980165],[-94.254764,44.980165],[-94.260241,45.281397],[-94.052118,45.423797]]]}}, -{"type":"Feature","id":"27173","properties":{"name":"Yellow Medicine"},"geometry":{"type":"Polygon","coordinates":[[[-95.733538,44.930872],[-95.481599,44.75561],[-95.361106,44.700841],[-95.596615,44.54201],[-95.936185,44.629641],[-96.095016,44.629641],[-96.44554,44.629641],[-96.451017,44.629641],[-96.451017,44.804903],[-95.739015,44.936349],[-95.733538,44.930872]]]}}, -{"type":"Feature","id":"28001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-91.319124,31.758831],[-91.154816,31.610953],[-91.160293,31.34806],[-91.264355,31.369968],[-91.587494,31.189229],[-91.379371,31.731446],[-91.346509,31.753354],[-91.319124,31.758831]]]}}, -{"type":"Feature","id":"28003","properties":{"name":"Alcorn"},"geometry":{"type":"Polygon","coordinates":[[[-88.471115,34.995703],[-88.378007,34.995703],[-88.361576,34.995703],[-88.367053,34.754717],[-88.717578,34.754717],[-88.821639,34.995703],[-88.788778,34.995703],[-88.471115,34.995703]]]}}, -{"type":"Feature","id":"28005","properties":{"name":"Amite"},"geometry":{"type":"Polygon","coordinates":[[[-90.722138,31.34806],[-90.634507,31.34806],[-90.546876,31.34806],[-90.546876,30.997536],[-90.568783,30.997536],[-90.8262,30.997536],[-91.061708,30.997536],[-91.09457,31.320676],[-90.722138,31.34806]]]}}, -{"type":"Feature","id":"28007","properties":{"name":"Attala"},"geometry":{"type":"Polygon","coordinates":[[[-89.396718,33.286897],[-89.320041,33.106158],[-89.320041,32.930896],[-89.473395,32.930896],[-89.730812,32.887081],[-89.96632,32.881604],[-89.747242,33.215697],[-89.643181,33.286897],[-89.451488,33.286897],[-89.396718,33.286897]]]}}, -{"type":"Feature","id":"28009","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-89.199548,34.995703],[-89.018809,34.995703],[-89.09001,34.595886],[-89.243364,34.584932],[-89.352903,34.995703],[-89.199548,34.995703]]]}}, -{"type":"Feature","id":"28011","properties":{"name":"Bolivar"},"geometry":{"type":"Polygon","coordinates":[[[-90.738569,34.119392],[-90.656414,33.987946],[-90.765953,33.527883],[-91.001462,33.527883],[-91.215062,33.527883],[-91.231493,33.560744],[-90.952169,34.119392],[-90.957646,34.119392],[-90.738569,34.119392]]]}}, -{"type":"Feature","id":"28013","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-89.511734,34.163208],[-89.243364,34.163208],[-89.139302,34.075577],[-89.194071,33.736006],[-89.506257,33.719575],[-89.506257,33.867453],[-89.511734,34.163208]]]}}, -{"type":"Feature","id":"28015","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-90.114197,33.67576],[-89.785581,33.67576],[-89.643181,33.286897],[-89.747242,33.215697],[-90.174444,33.330713],[-90.130628,33.67576],[-90.114197,33.67576]]]}}, -{"type":"Feature","id":"28017","properties":{"name":"Chickasaw"},"geometry":{"type":"Polygon","coordinates":[[[-88.827116,34.075577],[-88.717578,34.075577],[-88.717578,33.812683],[-88.887363,33.812683],[-89.03524,33.741483],[-89.117394,33.741483],[-89.194071,33.736006],[-89.139302,34.075577],[-88.827116,34.075577]]]}}, -{"type":"Feature","id":"28019","properties":{"name":"Choctaw"},"geometry":{"type":"Polygon","coordinates":[[[-89.139302,33.53336],[-89.09001,33.53336],[-89.09001,33.286897],[-89.320041,33.106158],[-89.396718,33.286897],[-89.451488,33.286897],[-89.380287,33.462159],[-89.139302,33.53336]]]}}, -{"type":"Feature","id":"28021","properties":{"name":"Claiborne"},"geometry":{"type":"Polygon","coordinates":[[[-90.727615,32.224371],[-90.716661,32.049109],[-90.738569,31.786216],[-91.247924,31.86837],[-91.028846,32.114832],[-90.727615,32.224371]]]}}, -{"type":"Feature","id":"28023","properties":{"name":"Clarke"},"geometry":{"type":"Polygon","coordinates":[[[-88.914747,32.224371],[-88.432777,32.229848],[-88.471115,31.895754],[-88.909271,31.824554],[-88.914747,32.224371]]]}}, -{"type":"Feature","id":"28025","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-88.887363,33.812683],[-88.717578,33.812683],[-88.514931,33.648375],[-88.673762,33.505975],[-89.018809,33.560744],[-89.03524,33.741483],[-88.887363,33.812683]]]}}, -{"type":"Feature","id":"28027","properties":{"name":"Coahoma"},"geometry":{"type":"Polygon","coordinates":[[[-90.568783,34.524686],[-90.398998,34.426101],[-90.448291,34.075577],[-90.448291,33.987946],[-90.656414,33.987946],[-90.738569,34.119392],[-90.957646,34.119392],[-90.568783,34.524686]]]}}, -{"type":"Feature","id":"28029","properties":{"name":"Copiah"},"geometry":{"type":"Polygon","coordinates":[[[-90.716661,32.049109],[-90.229213,32.049109],[-90.125151,31.753354],[-90.245644,31.715015],[-90.311367,31.698584],[-90.738569,31.698584],[-90.738569,31.786216],[-90.716661,32.049109]]]}}, -{"type":"Feature","id":"28031","properties":{"name":"Covington"},"geometry":{"type":"Polygon","coordinates":[[[-89.402195,31.797169],[-89.396718,31.435691],[-89.42958,31.435691],[-89.451488,31.435691],[-89.588411,31.435691],[-89.752719,31.775262],[-89.654134,31.780739],[-89.402195,31.797169]]]}}, -{"type":"Feature","id":"28033","properties":{"name":"DeSoto"},"geometry":{"type":"Polygon","coordinates":[[[-89.829396,34.995703],[-89.725335,34.995703],[-89.725335,34.771148],[-89.845827,34.771148],[-90.201828,34.721856],[-90.267552,34.858779],[-90.30589,34.858779],[-90.311367,34.995703],[-89.829396,34.995703]]]}}, -{"type":"Feature","id":"28035","properties":{"name":"Forrest"},"geometry":{"type":"Polygon","coordinates":[[[-89.42958,31.435691],[-89.396718,31.435691],[-89.144779,31.435691],[-89.139302,30.909905],[-89.341949,30.909905],[-89.347426,31.00849],[-89.451488,31.435691],[-89.42958,31.435691]]]}}, -{"type":"Feature","id":"28037","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-91.154816,31.610953],[-90.738569,31.610953],[-90.634507,31.34806],[-90.722138,31.34806],[-91.09457,31.320676],[-91.160293,31.34806],[-91.154816,31.610953]]]}}, -{"type":"Feature","id":"28039","properties":{"name":"George"},"geometry":{"type":"Polygon","coordinates":[[[-88.679239,30.997536],[-88.4273,30.997536],[-88.410869,30.734643],[-88.865455,30.734643],[-88.881886,30.734643],[-88.887363,30.909905],[-88.832593,30.997536],[-88.679239,30.997536]]]}}, -{"type":"Feature","id":"28041","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-88.460161,31.435691],[-88.449208,31.435691],[-88.432777,31.112552],[-88.4273,30.997536],[-88.679239,30.997536],[-88.832593,30.997536],[-88.843547,31.435691],[-88.460161,31.435691]]]}}, -{"type":"Feature","id":"28043","properties":{"name":"Grenada"},"geometry":{"type":"Polygon","coordinates":[[[-89.927981,33.900315],[-89.506257,33.867453],[-89.506257,33.719575],[-89.506257,33.67576],[-89.785581,33.67576],[-90.114197,33.67576],[-90.130628,33.67576],[-90.136105,33.719575],[-89.927981,33.900315]]]}}, -{"type":"Feature","id":"28045","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-89.495303,30.647012],[-89.341949,30.647012],[-89.341949,30.373165],[-89.522688,30.181472],[-89.686996,30.460796],[-89.495303,30.647012]]]}}, -{"type":"Feature","id":"28047","properties":{"name":"Harrison"},"geometry":{"type":"Polygon","coordinates":[[[-88.881886,30.679874],[-88.843547,30.406027],[-89.341949,30.373165],[-89.341949,30.647012],[-88.881886,30.679874]]]}}, -{"type":"Feature","id":"28049","properties":{"name":"Hinds"},"geometry":{"type":"Polygon","coordinates":[[[-90.486629,32.542033],[-90.448291,32.574895],[-90.064905,32.399633],[-90.229213,32.049109],[-90.716661,32.049109],[-90.727615,32.224371],[-90.552353,32.509172],[-90.486629,32.542033]]]}}, -{"type":"Feature","id":"28051","properties":{"name":"Holmes"},"geometry":{"type":"Polygon","coordinates":[[[-90.174444,33.330713],[-89.747242,33.215697],[-89.96632,32.881604],[-90.366137,33.01305],[-90.333275,33.303328],[-90.174444,33.330713]]]}}, -{"type":"Feature","id":"28053","properties":{"name":"Humphreys"},"geometry":{"type":"Polygon","coordinates":[[[-90.453768,33.330713],[-90.333275,33.303328],[-90.366137,33.01305],[-90.656414,32.919942],[-90.70023,33.095204],[-90.716661,33.270466],[-90.453768,33.330713]]]}}, -{"type":"Feature","id":"28055","properties":{"name":"Issaquena"},"geometry":{"type":"Polygon","coordinates":[[[-90.913831,33.007573],[-90.722138,32.662526],[-90.722138,32.61871],[-91.045277,32.574895],[-91.16577,33.002096],[-91.16577,33.01305],[-90.913831,33.007573]]]}}, -{"type":"Feature","id":"28057","properties":{"name":"Itawamba"},"geometry":{"type":"Polygon","coordinates":[[[-88.493023,34.464439],[-88.328715,34.464439],[-88.15893,34.464439],[-88.175361,34.322039],[-88.202745,34.08653],[-88.542316,34.08653],[-88.542316,34.464439],[-88.493023,34.464439]]]}}, -{"type":"Feature","id":"28059","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-88.865455,30.734643],[-88.410869,30.734643],[-88.394438,30.367688],[-88.843547,30.406027],[-88.881886,30.679874],[-88.881886,30.734643],[-88.865455,30.734643]]]}}, -{"type":"Feature","id":"28061","properties":{"name":"Jasper"},"geometry":{"type":"Polygon","coordinates":[[[-89.018809,32.224371],[-88.914747,32.224371],[-88.909271,31.824554],[-88.942132,31.824554],[-89.314564,31.802646],[-89.320041,32.224371],[-89.018809,32.224371]]]}}, -{"type":"Feature","id":"28063","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-91.247924,31.86837],[-90.738569,31.786216],[-90.738569,31.698584],[-90.738569,31.610953],[-91.154816,31.610953],[-91.319124,31.758831],[-91.346509,31.753354],[-91.247924,31.86837]]]}}, -{"type":"Feature","id":"28065","properties":{"name":"Jefferson Davis"},"geometry":{"type":"Polygon","coordinates":[[[-89.977274,31.764308],[-89.752719,31.775262],[-89.588411,31.435691],[-89.654134,31.435691],[-89.659611,31.435691],[-89.960843,31.391876],[-89.977274,31.753354],[-89.977274,31.764308]]]}}, -{"type":"Feature","id":"28067","properties":{"name":"Jones"},"geometry":{"type":"Polygon","coordinates":[[[-88.942132,31.824554],[-88.942132,31.435691],[-89.144779,31.435691],[-89.396718,31.435691],[-89.402195,31.797169],[-89.314564,31.802646],[-88.942132,31.824554]]]}}, -{"type":"Feature","id":"28069","properties":{"name":"Kemper"},"geometry":{"type":"Polygon","coordinates":[[[-88.345146,32.930896],[-88.388961,32.580372],[-88.651854,32.574895],[-88.914747,32.574895],[-88.914747,32.925419],[-88.810686,32.925419],[-88.345146,32.930896]]]}}, -{"type":"Feature","id":"28071","properties":{"name":"Lafayette"},"geometry":{"type":"Polygon","coordinates":[[[-89.62675,34.557547],[-89.248841,34.497301],[-89.248841,34.376808],[-89.243364,34.163208],[-89.511734,34.163208],[-89.719858,34.190592],[-89.719858,34.55207],[-89.670565,34.55207],[-89.62675,34.557547]]]}}, -{"type":"Feature","id":"28073","properties":{"name":"Lamar"},"geometry":{"type":"Polygon","coordinates":[[[-89.451488,31.435691],[-89.347426,31.00849],[-89.599365,31.003013],[-89.654134,31.003013],[-89.654134,31.435691],[-89.588411,31.435691],[-89.451488,31.435691]]]}}, -{"type":"Feature","id":"28075","properties":{"name":"Lauderdale"},"geometry":{"type":"Polygon","coordinates":[[[-88.651854,32.574895],[-88.388961,32.580372],[-88.421823,32.306525],[-88.432777,32.229848],[-88.914747,32.224371],[-88.914747,32.574895],[-88.651854,32.574895]]]}}, -{"type":"Feature","id":"28077","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-89.977274,31.753354],[-89.960843,31.391876],[-90.042997,31.337106],[-90.190875,31.34806],[-90.245644,31.34806],[-90.245644,31.715015],[-90.125151,31.753354],[-89.977274,31.764308],[-89.977274,31.753354]]]}}, -{"type":"Feature","id":"28079","properties":{"name":"Leake"},"geometry":{"type":"Polygon","coordinates":[[[-89.473395,32.930896],[-89.320041,32.930896],[-89.320041,32.574895],[-89.320041,32.574895],[-89.730812,32.635141],[-89.730812,32.887081],[-89.473395,32.930896]]]}}, -{"type":"Feature","id":"28081","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-88.635423,34.508255],[-88.542316,34.464439],[-88.542316,34.08653],[-88.706624,34.092007],[-88.717578,34.075577],[-88.827116,34.075577],[-88.827116,34.365854],[-88.734008,34.508255],[-88.635423,34.508255]]]}}, -{"type":"Feature","id":"28083","properties":{"name":"Leflore"},"geometry":{"type":"Polygon","coordinates":[[[-90.453768,33.812683],[-90.136105,33.719575],[-90.130628,33.67576],[-90.174444,33.330713],[-90.333275,33.303328],[-90.453768,33.330713],[-90.453768,33.812683]]]}}, -{"type":"Feature","id":"28085","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-90.311367,31.698584],[-90.245644,31.715015],[-90.245644,31.34806],[-90.262075,31.34806],[-90.355183,31.34806],[-90.546876,31.34806],[-90.634507,31.34806],[-90.738569,31.610953],[-90.738569,31.698584],[-90.311367,31.698584]]]}}, -{"type":"Feature","id":"28087","properties":{"name":"Lowndes"},"geometry":{"type":"Polygon","coordinates":[[[-88.246561,33.74696],[-88.273945,33.53336],[-88.306807,33.286897],[-88.668285,33.286897],[-88.673762,33.505975],[-88.514931,33.648375],[-88.246561,33.74696]]]}}, -{"type":"Feature","id":"28089","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-89.96632,32.881604],[-89.730812,32.887081],[-89.730812,32.635141],[-89.785581,32.585849],[-90.03752,32.448925],[-90.064905,32.399633],[-90.448291,32.574895],[-89.96632,32.881604]]]}}, -{"type":"Feature","id":"28091","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-89.659611,31.435691],[-89.654134,31.435691],[-89.654134,31.003013],[-89.730812,31.003013],[-89.834873,31.003013],[-90.042997,31.337106],[-89.960843,31.391876],[-89.659611,31.435691]]]}}, -{"type":"Feature","id":"28093","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-89.643181,34.995703],[-89.352903,34.995703],[-89.243364,34.584932],[-89.248841,34.497301],[-89.62675,34.557547],[-89.670565,34.55207],[-89.725335,34.771148],[-89.725335,34.995703],[-89.643181,34.995703]]]}}, -{"type":"Feature","id":"28095","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-88.706624,34.092007],[-88.542316,34.08653],[-88.202745,34.08653],[-88.208222,34.059146],[-88.246561,33.74696],[-88.514931,33.648375],[-88.717578,33.812683],[-88.717578,34.075577],[-88.706624,34.092007]]]}}, -{"type":"Feature","id":"28097","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-89.506257,33.67576],[-89.380287,33.462159],[-89.451488,33.286897],[-89.643181,33.286897],[-89.785581,33.67576],[-89.506257,33.67576]]]}}, -{"type":"Feature","id":"28099","properties":{"name":"Neshoba"},"geometry":{"type":"Polygon","coordinates":[[[-89.155733,32.930896],[-88.914747,32.925419],[-88.914747,32.574895],[-89.133825,32.574895],[-89.320041,32.574895],[-89.320041,32.930896],[-89.155733,32.930896]]]}}, -{"type":"Feature","id":"28101","properties":{"name":"Newton"},"geometry":{"type":"Polygon","coordinates":[[[-89.133825,32.574895],[-88.914747,32.574895],[-88.914747,32.224371],[-89.018809,32.224371],[-89.320041,32.224371],[-89.320041,32.574895],[-89.320041,32.574895],[-89.133825,32.574895]]]}}, -{"type":"Feature","id":"28103","properties":{"name":"Noxubee"},"geometry":{"type":"Polygon","coordinates":[[[-88.668285,33.286897],[-88.306807,33.286897],[-88.339669,32.991142],[-88.345146,32.930896],[-88.810686,32.925419],[-88.810686,33.286897],[-88.668285,33.286897]]]}}, -{"type":"Feature","id":"28105","properties":{"name":"Oktibbeha"},"geometry":{"type":"Polygon","coordinates":[[[-89.051671,33.560744],[-89.018809,33.560744],[-88.673762,33.505975],[-88.668285,33.286897],[-88.810686,33.286897],[-89.09001,33.286897],[-89.09001,33.53336],[-89.051671,33.560744]]]}}, -{"type":"Feature","id":"28107","properties":{"name":"Panola"},"geometry":{"type":"Polygon","coordinates":[[[-90.097767,34.55207],[-89.719858,34.55207],[-89.719858,34.190592],[-89.933458,34.163208],[-90.136105,34.157731],[-90.196352,34.508255],[-90.196352,34.55207],[-90.097767,34.55207]]]}}, -{"type":"Feature","id":"28109","properties":{"name":"Pearl River"},"geometry":{"type":"Polygon","coordinates":[[[-89.599365,31.003013],[-89.347426,31.00849],[-89.341949,30.909905],[-89.341949,30.647012],[-89.495303,30.647012],[-89.686996,30.460796],[-89.84035,30.663443],[-89.730812,31.003013],[-89.654134,31.003013],[-89.599365,31.003013]]]}}, -{"type":"Feature","id":"28111","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-89.144779,31.435691],[-88.942132,31.435691],[-88.843547,31.435691],[-88.832593,30.997536],[-88.887363,30.909905],[-88.996902,30.909905],[-89.139302,30.909905],[-89.144779,31.435691]]]}}, -{"type":"Feature","id":"28113","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-90.355183,31.34806],[-90.262075,31.34806],[-90.262075,31.003013],[-90.349706,31.003013],[-90.371614,30.997536],[-90.546876,30.997536],[-90.546876,31.34806],[-90.355183,31.34806]]]}}, -{"type":"Feature","id":"28115","properties":{"name":"Pontotoc"},"geometry":{"type":"Polygon","coordinates":[[[-89.09001,34.382285],[-88.827116,34.365854],[-88.827116,34.075577],[-89.139302,34.075577],[-89.243364,34.163208],[-89.248841,34.376808],[-89.09001,34.382285]]]}}, -{"type":"Feature","id":"28117","properties":{"name":"Prentiss"},"geometry":{"type":"Polygon","coordinates":[[[-88.717578,34.754717],[-88.367053,34.754717],[-88.328715,34.464439],[-88.493023,34.464439],[-88.542316,34.464439],[-88.635423,34.508255],[-88.734008,34.508255],[-88.734008,34.595886],[-88.717578,34.754717]]]}}, -{"type":"Feature","id":"28119","properties":{"name":"Quitman"},"geometry":{"type":"Polygon","coordinates":[[[-90.196352,34.508255],[-90.136105,34.157731],[-90.448291,34.075577],[-90.398998,34.426101],[-90.196352,34.508255]]]}}, -{"type":"Feature","id":"28121","properties":{"name":"Rankin"},"geometry":{"type":"Polygon","coordinates":[[[-90.03752,32.448925],[-89.785581,32.585849],[-89.730812,32.224371],[-89.730812,32.049109],[-90.190875,32.049109],[-90.229213,32.049109],[-90.064905,32.399633],[-90.03752,32.448925]]]}}, -{"type":"Feature","id":"28123","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-89.730812,32.635141],[-89.320041,32.574895],[-89.320041,32.224371],[-89.456965,32.224371],[-89.730812,32.224371],[-89.785581,32.585849],[-89.730812,32.635141]]]}}, -{"type":"Feature","id":"28125","properties":{"name":"Sharkey"},"geometry":{"type":"Polygon","coordinates":[[[-90.913831,33.095204],[-90.70023,33.095204],[-90.656414,32.919942],[-90.722138,32.662526],[-90.913831,33.007573],[-90.913831,33.095204]]]}}, -{"type":"Feature","id":"28127","properties":{"name":"Simpson"},"geometry":{"type":"Polygon","coordinates":[[[-90.190875,32.049109],[-89.730812,32.049109],[-89.654134,31.780739],[-89.752719,31.775262],[-89.977274,31.764308],[-90.125151,31.753354],[-90.229213,32.049109],[-90.190875,32.049109]]]}}, -{"type":"Feature","id":"28129","properties":{"name":"Smith"},"geometry":{"type":"Polygon","coordinates":[[[-89.456965,32.224371],[-89.320041,32.224371],[-89.314564,31.802646],[-89.402195,31.797169],[-89.654134,31.780739],[-89.730812,32.049109],[-89.730812,32.224371],[-89.456965,32.224371]]]}}, -{"type":"Feature","id":"28131","properties":{"name":"Stone"},"geometry":{"type":"Polygon","coordinates":[[[-88.996902,30.909905],[-88.887363,30.909905],[-88.881886,30.734643],[-88.881886,30.679874],[-89.341949,30.647012],[-89.341949,30.909905],[-89.139302,30.909905],[-88.996902,30.909905]]]}}, -{"type":"Feature","id":"28133","properties":{"name":"Sunflower"},"geometry":{"type":"Polygon","coordinates":[[[-90.448291,33.987946],[-90.453768,33.812683],[-90.453768,33.330713],[-90.716661,33.270466],[-90.765953,33.527883],[-90.656414,33.987946],[-90.448291,33.987946]]]}}, -{"type":"Feature","id":"28135","properties":{"name":"Tallahatchie"},"geometry":{"type":"Polygon","coordinates":[[[-89.933458,34.163208],[-89.927981,33.900315],[-90.136105,33.719575],[-90.453768,33.812683],[-90.448291,33.987946],[-90.448291,34.075577],[-90.136105,34.157731],[-89.933458,34.163208]]]}}, -{"type":"Feature","id":"28137","properties":{"name":"Tate"},"geometry":{"type":"Polygon","coordinates":[[[-89.845827,34.771148],[-89.725335,34.771148],[-89.670565,34.55207],[-89.719858,34.55207],[-90.097767,34.55207],[-90.196352,34.55207],[-90.201828,34.721856],[-89.845827,34.771148]]]}}, -{"type":"Feature","id":"28139","properties":{"name":"Tippah"},"geometry":{"type":"Polygon","coordinates":[[[-89.018809,34.995703],[-88.821639,34.995703],[-88.717578,34.754717],[-88.734008,34.595886],[-89.09001,34.595886],[-89.018809,34.995703]]]}}, -{"type":"Feature","id":"28141","properties":{"name":"Tishomingo"},"geometry":{"type":"Polygon","coordinates":[[[-88.252038,34.995703],[-88.202745,34.995703],[-88.098683,34.891641],[-88.142499,34.579455],[-88.15893,34.464439],[-88.328715,34.464439],[-88.367053,34.754717],[-88.361576,34.995703],[-88.252038,34.995703]]]}}, -{"type":"Feature","id":"28143","properties":{"name":"Tunica"},"geometry":{"type":"Polygon","coordinates":[[[-90.267552,34.858779],[-90.201828,34.721856],[-90.196352,34.55207],[-90.196352,34.508255],[-90.398998,34.426101],[-90.568783,34.524686],[-90.585214,34.639701],[-90.409952,34.831394],[-90.30589,34.858779],[-90.267552,34.858779]]]}}, -{"type":"Feature","id":"28145","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-89.09001,34.595886],[-88.734008,34.595886],[-88.734008,34.508255],[-88.827116,34.365854],[-89.09001,34.382285],[-89.248841,34.376808],[-89.248841,34.497301],[-89.243364,34.584932],[-89.09001,34.595886]]]}}, -{"type":"Feature","id":"28147","properties":{"name":"Walthall"},"geometry":{"type":"Polygon","coordinates":[[[-90.190875,31.34806],[-90.042997,31.337106],[-89.834873,31.003013],[-90.262075,31.003013],[-90.262075,31.34806],[-90.245644,31.34806],[-90.190875,31.34806]]]}}, -{"type":"Feature","id":"28149","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-91.045277,32.574895],[-90.722138,32.61871],[-90.552353,32.509172],[-90.727615,32.224371],[-91.028846,32.114832],[-91.028846,32.120309],[-91.050754,32.125786],[-91.121954,32.213417],[-91.067185,32.563941],[-91.045277,32.574895]]]}}, -{"type":"Feature","id":"28151","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-91.001462,33.527883],[-90.765953,33.527883],[-90.716661,33.270466],[-90.70023,33.095204],[-90.913831,33.095204],[-90.913831,33.007573],[-91.16577,33.01305],[-91.215062,33.527883],[-91.001462,33.527883]]]}}, -{"type":"Feature","id":"28153","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-88.471115,31.895754],[-88.465638,31.698584],[-88.449208,31.435691],[-88.460161,31.435691],[-88.843547,31.435691],[-88.942132,31.435691],[-88.942132,31.824554],[-88.909271,31.824554],[-88.471115,31.895754]]]}}, -{"type":"Feature","id":"28155","properties":{"name":"Webster"},"geometry":{"type":"Polygon","coordinates":[[[-89.117394,33.741483],[-89.03524,33.741483],[-89.018809,33.560744],[-89.051671,33.560744],[-89.09001,33.53336],[-89.139302,33.53336],[-89.380287,33.462159],[-89.506257,33.67576],[-89.506257,33.719575],[-89.194071,33.736006],[-89.117394,33.741483]]]}}, -{"type":"Feature","id":"28157","properties":{"name":"Wilkinson"},"geometry":{"type":"Polygon","coordinates":[[[-91.264355,31.369968],[-91.160293,31.34806],[-91.09457,31.320676],[-91.061708,30.997536],[-91.176724,30.997536],[-91.636787,30.997536],[-91.587494,31.189229],[-91.264355,31.369968]]]}}, -{"type":"Feature","id":"28159","properties":{"name":"Winston"},"geometry":{"type":"Polygon","coordinates":[[[-89.09001,33.286897],[-88.810686,33.286897],[-88.810686,32.925419],[-88.914747,32.925419],[-89.155733,32.930896],[-89.320041,32.930896],[-89.320041,33.106158],[-89.09001,33.286897]]]}}, -{"type":"Feature","id":"28161","properties":{"name":"Yalobusha"},"geometry":{"type":"Polygon","coordinates":[[[-89.511734,34.163208],[-89.506257,33.867453],[-89.927981,33.900315],[-89.933458,34.163208],[-89.719858,34.190592],[-89.511734,34.163208]]]}}, -{"type":"Feature","id":"28163","properties":{"name":"Yazoo"},"geometry":{"type":"Polygon","coordinates":[[[-90.366137,33.01305],[-89.96632,32.881604],[-90.448291,32.574895],[-90.486629,32.542033],[-90.552353,32.509172],[-90.722138,32.61871],[-90.722138,32.662526],[-90.656414,32.919942],[-90.366137,33.01305]]]}}, -{"type":"Feature","id":"29001","properties":{"name":"Adair"},"geometry":{"type":"Polygon","coordinates":[[[-92.348789,40.346673],[-92.348789,40.302858],[-92.343312,40.039965],[-92.677405,40.039965],[-92.847191,40.039965],[-92.858145,40.039965],[-92.858145,40.341196],[-92.682882,40.341196],[-92.348789,40.346673]]]}}, -{"type":"Feature","id":"29003","properties":{"name":"Andrew"},"geometry":{"type":"Polygon","coordinates":[[[-95.043444,40.127596],[-94.605288,40.127596],[-94.605288,40.039965],[-94.605288,39.820887],[-94.769597,39.820887],[-94.879136,39.820887],[-94.994151,39.897564],[-95.043444,40.127596]]]}}, -{"type":"Feature","id":"29005","properties":{"name":"Atchison"},"geometry":{"type":"Polygon","coordinates":[[[-95.7664,40.587659],[-95.37206,40.582182],[-95.202275,40.576705],[-95.180367,40.264519],[-95.503507,40.264519],[-95.552799,40.264519],[-95.71163,40.521935],[-95.7664,40.587659]]]}}, -{"type":"Feature","id":"29007","properties":{"name":"Audrain"},"geometry":{"type":"Polygon","coordinates":[[[-92.31045,39.34987],[-91.718941,39.338916],[-91.439617,39.317009],[-91.406755,39.141746],[-91.625833,39.147223],[-91.63131,39.059592],[-92.107804,39.065069],[-92.315927,39.245808],[-92.31045,39.34987]]]}}, -{"type":"Feature","id":"29009","properties":{"name":"Barry"},"geometry":{"type":"Polygon","coordinates":[[[-94.008302,36.929063],[-93.608485,36.923586],[-93.586578,36.496384],[-93.728978,36.496384],[-93.865902,36.496384],[-94.079502,36.496384],[-94.068548,36.748324],[-94.063071,36.929063],[-94.008302,36.929063]]]}}, -{"type":"Feature","id":"29011","properties":{"name":"Barton"},"geometry":{"type":"Polygon","coordinates":[[[-94.490273,37.652019],[-94.074025,37.641065],[-94.074025,37.580818],[-94.079502,37.350787],[-94.577904,37.361741],[-94.616242,37.361741],[-94.616242,37.652019],[-94.490273,37.652019]]]}}, -{"type":"Feature","id":"29013","properties":{"name":"Bates"},"geometry":{"type":"Polygon","coordinates":[[[-94.610765,38.479037],[-94.063071,38.446175],[-94.052118,38.216144],[-94.057594,38.035405],[-94.501227,38.057312],[-94.616242,38.062789],[-94.610765,38.391406],[-94.610765,38.479037],[-94.610765,38.479037]]]}}, -{"type":"Feature","id":"29015","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-93.159376,38.533806],[-93.066268,38.528329],[-93.077222,38.259959],[-93.066268,38.062789],[-93.411315,38.068266],[-93.504423,38.073743],[-93.520854,38.20519],[-93.515377,38.511898],[-93.159376,38.533806]]]}}, -{"type":"Feature","id":"29017","properties":{"name":"Bollinger"},"geometry":{"type":"Polygon","coordinates":[[[-89.862258,37.597249],[-89.867735,37.126232],[-90.10872,37.038601],[-90.218259,37.312448],[-90.147059,37.597249],[-89.862258,37.597249]]]}}, -{"type":"Feature","id":"29019","properties":{"name":"Boone"},"geometry":{"type":"Polygon","coordinates":[[[-92.430943,39.251285],[-92.315927,39.245808],[-92.107804,39.065069],[-92.222819,38.643345],[-92.392605,38.736453],[-92.463805,38.862422],[-92.496666,38.922669],[-92.556913,38.971961],[-92.430943,39.251285]]]}}, -{"type":"Feature","id":"29021","properties":{"name":"Buchanan"},"geometry":{"type":"Polygon","coordinates":[[[-94.769597,39.820887],[-94.605288,39.820887],[-94.599812,39.749687],[-94.599812,39.530609],[-95.10369,39.530609],[-95.054398,39.623717],[-94.879136,39.820887],[-94.769597,39.820887]]]}}, -{"type":"Feature","id":"29023","properties":{"name":"Butler"},"geometry":{"type":"Polygon","coordinates":[[[-90.568783,36.929063],[-90.256598,36.923586],[-90.147059,36.633308],[-90.218259,36.496384],[-90.57426,36.496384],[-90.661891,36.814047],[-90.678322,36.929063],[-90.568783,36.929063]]]}}, -{"type":"Feature","id":"29025","properties":{"name":"Caldwell"},"geometry":{"type":"Polygon","coordinates":[[[-93.871378,39.788025],[-93.756363,39.782548],[-93.756363,39.612763],[-93.76184,39.525132],[-94.10141,39.525132],[-94.210949,39.525132],[-94.205472,39.74421],[-94.205472,39.788025],[-93.871378,39.788025]]]}}, -{"type":"Feature","id":"29027","properties":{"name":"Callaway"},"geometry":{"type":"Polygon","coordinates":[[[-92.107804,39.065069],[-91.63131,39.059592],[-91.647741,38.703591],[-92.009219,38.572145],[-92.222819,38.643345],[-92.107804,39.065069]]]}}, -{"type":"Feature","id":"29029","properties":{"name":"Camden"},"geometry":{"type":"Polygon","coordinates":[[[-93.077222,38.259959],[-92.693836,38.22162],[-92.403558,38.018974],[-92.409035,37.860142],[-92.852668,37.893004],[-93.071745,37.903958],[-93.066268,38.062789],[-93.077222,38.259959]]]}}, -{"type":"Feature","id":"29031","properties":{"name":"Cape Girardeau"},"geometry":{"type":"Polygon","coordinates":[[[-89.796535,37.602726],[-89.522688,37.564388],[-89.484349,37.334356],[-89.489826,37.252202],[-89.763673,37.126232],[-89.867735,37.126232],[-89.867735,37.126232],[-89.862258,37.597249],[-89.796535,37.602726]]]}}, -{"type":"Feature","id":"29033","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-93.422269,39.612763],[-93.279869,39.61824],[-93.104607,39.382732],[-93.274392,39.317009],[-93.477039,39.295101],[-93.597531,39.240331],[-93.756363,39.20747],[-93.76184,39.525132],[-93.756363,39.612763],[-93.422269,39.612763]]]}}, -{"type":"Feature","id":"29035","properties":{"name":"Carter"},"geometry":{"type":"Polygon","coordinates":[[[-91.220539,37.038601],[-91.017893,37.093371],[-90.776907,37.049555],[-90.678322,36.929063],[-90.661891,36.814047],[-90.935738,36.814047],[-91.116477,36.825001],[-91.220539,36.885247],[-91.220539,37.038601]]]}}, -{"type":"Feature","id":"29037","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-94.583381,38.845992],[-94.117841,38.835038],[-94.063071,38.566668],[-94.063071,38.446175],[-94.610765,38.479037],[-94.610765,38.479037],[-94.610765,38.736453],[-94.610765,38.845992],[-94.583381,38.845992]]]}}, -{"type":"Feature","id":"29039","properties":{"name":"Cedar"},"geometry":{"type":"Polygon","coordinates":[[[-94.063071,37.898481],[-93.630393,37.827281],[-93.613962,37.575342],[-94.074025,37.580818],[-94.074025,37.641065],[-94.063071,37.898481]]]}}, -{"type":"Feature","id":"29041","properties":{"name":"Chariton"},"geometry":{"type":"Polygon","coordinates":[[[-93.04436,39.705871],[-92.858145,39.700394],[-92.693836,39.612763],[-92.70479,39.322485],[-92.847191,39.223901],[-93.104607,39.382732],[-93.279869,39.61824],[-93.268915,39.705871],[-93.04436,39.705871]]]}}, -{"type":"Feature","id":"29043","properties":{"name":"Christian"},"geometry":{"type":"Polygon","coordinates":[[[-93.482516,37.098848],[-93.066268,37.087894],[-92.90196,37.071463],[-92.907437,36.80857],[-93.301777,36.819524],[-93.592055,36.994786],[-93.608485,36.994786],[-93.608485,37.098848],[-93.482516,37.098848]]]}}, -{"type":"Feature","id":"29045","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-91.833957,40.609566],[-91.718941,40.598613],[-91.417709,40.379535],[-91.499863,40.248088],[-91.948972,40.259042],[-91.948972,40.302858],[-91.943495,40.60409],[-91.833957,40.609566]]]}}, -{"type":"Feature","id":"29047","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-94.56695,39.453932],[-94.210949,39.453932],[-94.210949,39.20747],[-94.419073,39.147223],[-94.605288,39.114362],[-94.599812,39.158177],[-94.599812,39.453932],[-94.56695,39.453932]]]}}, -{"type":"Feature","id":"29049","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-94.506704,39.749687],[-94.205472,39.74421],[-94.210949,39.525132],[-94.210949,39.453932],[-94.56695,39.453932],[-94.599812,39.453932],[-94.599812,39.530609],[-94.599812,39.749687],[-94.506704,39.749687]]]}}, -{"type":"Feature","id":"29051","properties":{"name":"Cole"},"geometry":{"type":"Polygon","coordinates":[[[-92.392605,38.736453],[-92.222819,38.643345],[-92.009219,38.572145],[-92.195435,38.336636],[-92.496666,38.429744],[-92.392605,38.736453]]]}}, -{"type":"Feature","id":"29053","properties":{"name":"Cooper"},"geometry":{"type":"Polygon","coordinates":[[[-92.918391,39.032208],[-92.556913,38.971961],[-92.496666,38.922669],[-92.841714,38.681683],[-93.060791,38.692637],[-93.049837,38.928146],[-92.934822,39.065069],[-92.918391,39.032208]]]}}, -{"type":"Feature","id":"29055","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-91.532725,38.210667],[-91.368417,38.210667],[-91.09457,38.20519],[-91.100047,37.73965],[-91.154816,37.695834],[-91.527248,37.788942],[-91.532725,38.15042],[-91.532725,38.210667]]]}}, -{"type":"Feature","id":"29057","properties":{"name":"Dade"},"geometry":{"type":"Polygon","coordinates":[[[-94.074025,37.580818],[-93.613962,37.575342],[-93.619439,37.427464],[-93.619439,37.427464],[-93.624916,37.279587],[-94.008302,37.290541],[-94.052118,37.290541],[-94.079502,37.350787],[-94.074025,37.580818]]]}}, -{"type":"Feature","id":"29059","properties":{"name":"Dallas"},"geometry":{"type":"Polygon","coordinates":[[[-93.126515,37.903958],[-93.071745,37.903958],[-92.852668,37.893004],[-92.852668,37.482234],[-93.071745,37.48771],[-93.071745,37.41651],[-93.181284,37.41651],[-93.186761,37.805373],[-93.126515,37.903958]]]}}, -{"type":"Feature","id":"29061","properties":{"name":"Daviess"},"geometry":{"type":"Polygon","coordinates":[[[-94.216426,40.13855],[-93.76184,40.133073],[-93.76184,39.957811],[-93.756363,39.782548],[-93.871378,39.788025],[-94.205472,39.788025],[-94.216426,40.034488],[-94.216426,40.13855]]]}}, -{"type":"Feature","id":"29063","properties":{"name":"DeKalb"},"geometry":{"type":"Polygon","coordinates":[[[-94.577904,40.039965],[-94.216426,40.034488],[-94.205472,39.788025],[-94.205472,39.74421],[-94.506704,39.749687],[-94.599812,39.749687],[-94.605288,39.820887],[-94.605288,40.039965],[-94.577904,40.039965]]]}}, -{"type":"Feature","id":"29065","properties":{"name":"Dent"},"geometry":{"type":"Polygon","coordinates":[[[-91.806572,37.597249],[-91.527248,37.788942],[-91.154816,37.695834],[-91.154816,37.586295],[-91.209585,37.41651],[-91.554633,37.421987],[-91.647741,37.421987],[-91.806572,37.597249]]]}}, -{"type":"Feature","id":"29067","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-92.688359,37.065986],[-92.250204,37.060509],[-92.091373,37.055032],[-92.113281,36.792139],[-92.529528,36.803093],[-92.765037,36.80857],[-92.907437,36.80857],[-92.90196,37.071463],[-92.688359,37.065986]]]}}, -{"type":"Feature","id":"29069","properties":{"name":"Dunklin"},"geometry":{"type":"Polygon","coordinates":[[[-90.048474,36.627831],[-89.960843,36.627831],[-89.960843,36.386845],[-89.960843,35.997983],[-90.289459,35.997983],[-90.377091,35.997983],[-90.190875,36.200629],[-90.218259,36.496384],[-90.147059,36.633308],[-90.048474,36.627831]]]}}, -{"type":"Feature","id":"29071","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-90.963123,38.550237],[-90.733092,38.637868],[-90.738569,38.47356],[-90.782384,38.20519],[-91.09457,38.20519],[-91.368417,38.210667],[-91.368417,38.698114],[-90.963123,38.550237]]]}}, -{"type":"Feature","id":"29073","properties":{"name":"Gasconade"},"geometry":{"type":"Polygon","coordinates":[[[-91.417709,38.709068],[-91.368417,38.698114],[-91.368417,38.210667],[-91.532725,38.210667],[-91.532725,38.15042],[-91.63131,38.155897],[-91.642264,38.287344],[-91.642264,38.703591],[-91.417709,38.709068]]]}}, -{"type":"Feature","id":"29075","properties":{"name":"Gentry"},"geometry":{"type":"Polygon","coordinates":[[[-94.325965,40.385012],[-94.216426,40.385012],[-94.216426,40.13855],[-94.216426,40.034488],[-94.577904,40.039965],[-94.605288,40.039965],[-94.605288,40.127596],[-94.599812,40.385012],[-94.325965,40.385012]]]}}, -{"type":"Feature","id":"29077","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-93.619439,37.427464],[-93.619439,37.427464],[-93.181284,37.41651],[-93.071745,37.41651],[-93.066268,37.087894],[-93.482516,37.098848],[-93.608485,37.098848],[-93.624916,37.279587],[-93.619439,37.427464]]]}}, -{"type":"Feature","id":"29079","properties":{"name":"Grundy"},"geometry":{"type":"Polygon","coordinates":[[[-93.3675,40.264519],[-93.362023,40.034488],[-93.362023,39.968764],[-93.76184,39.957811],[-93.76184,40.133073],[-93.76184,40.264519],[-93.3675,40.264519]]]}}, -{"type":"Feature","id":"29081","properties":{"name":"Harrison"},"geometry":{"type":"Polygon","coordinates":[[[-93.772794,40.576705],[-93.76184,40.264519],[-93.76184,40.133073],[-94.216426,40.13855],[-94.216426,40.385012],[-94.232857,40.571228],[-94.013779,40.571228],[-93.772794,40.576705]]]}}, -{"type":"Feature","id":"29083","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-93.794701,38.561191],[-93.5099,38.555714],[-93.515377,38.511898],[-93.520854,38.20519],[-93.772794,38.20519],[-94.052118,38.216144],[-94.063071,38.446175],[-94.063071,38.566668],[-93.794701,38.561191]]]}}, -{"type":"Feature","id":"29085","properties":{"name":"Hickory"},"geometry":{"type":"Polygon","coordinates":[[[-93.411315,38.068266],[-93.066268,38.062789],[-93.071745,37.903958],[-93.126515,37.903958],[-93.186761,37.805373],[-93.575624,37.827281],[-93.504423,38.073743],[-93.411315,38.068266]]]}}, -{"type":"Feature","id":"29087","properties":{"name":"Holt"},"geometry":{"type":"Polygon","coordinates":[[[-95.503507,40.264519],[-95.180367,40.264519],[-95.043444,40.127596],[-94.994151,39.897564],[-95.306337,40.001626],[-95.552799,40.264519],[-95.552799,40.264519],[-95.503507,40.264519]]]}}, -{"type":"Feature","id":"29089","properties":{"name":"Howard"},"geometry":{"type":"Polygon","coordinates":[[[-92.847191,39.223901],[-92.70479,39.322485],[-92.430943,39.251285],[-92.556913,38.971961],[-92.918391,39.032208],[-92.934822,39.065069],[-92.847191,39.223901]]]}}, -{"type":"Feature","id":"29091","properties":{"name":"Howell"},"geometry":{"type":"Polygon","coordinates":[[[-92.074942,37.055032],[-91.653218,37.049555],[-91.658695,36.890724],[-91.669648,36.501861],[-92.118758,36.496384],[-92.113281,36.792139],[-92.091373,37.055032],[-92.074942,37.055032]]]}}, -{"type":"Feature","id":"29093","properties":{"name":"Iron"},"geometry":{"type":"Polygon","coordinates":[[[-90.645461,37.734173],[-90.535922,37.641065],[-90.552353,37.317925],[-90.733092,37.268633],[-90.77143,37.476757],[-91.154816,37.586295],[-91.154816,37.695834],[-91.100047,37.73965],[-90.645461,37.734173]]]}}, -{"type":"Feature","id":"29095","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-94.419073,39.147223],[-94.210949,39.20747],[-94.106887,39.141746],[-94.112364,38.917192],[-94.117841,38.835038],[-94.583381,38.845992],[-94.610765,38.845992],[-94.605288,39.043162],[-94.605288,39.114362],[-94.419073,39.147223]]]}}, -{"type":"Feature","id":"29097","properties":{"name":"Jasper"},"geometry":{"type":"Polygon","coordinates":[[[-94.577904,37.361741],[-94.079502,37.350787],[-94.052118,37.290541],[-94.057594,37.049555],[-94.616242,37.055032],[-94.616242,37.339833],[-94.616242,37.361741],[-94.577904,37.361741]]]}}, -{"type":"Feature","id":"29099","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-90.464722,38.500944],[-90.344229,38.385929],[-90.251121,38.128512],[-90.415429,38.040881],[-90.639984,38.07922],[-90.782384,38.20519],[-90.738569,38.47356],[-90.464722,38.500944]]]}}, -{"type":"Feature","id":"29101","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-93.800178,38.9391],[-93.498947,38.928146],[-93.5099,38.555714],[-93.794701,38.561191],[-94.063071,38.566668],[-94.117841,38.835038],[-94.112364,38.917192],[-93.800178,38.9391]]]}}, -{"type":"Feature","id":"29103","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-92.140665,40.302858],[-91.948972,40.302858],[-91.948972,40.259042],[-91.954449,39.946857],[-91.998265,39.952334],[-92.288543,39.952334],[-92.343312,40.039965],[-92.348789,40.302858],[-92.140665,40.302858]]]}}, -{"type":"Feature","id":"29105","properties":{"name":"Laclede"},"geometry":{"type":"Polygon","coordinates":[[[-92.852668,37.893004],[-92.409035,37.860142],[-92.250204,37.602726],[-92.250204,37.47128],[-92.688359,37.482234],[-92.852668,37.482234],[-92.852668,37.893004]]]}}, -{"type":"Feature","id":"29107","properties":{"name":"Lafayette"},"geometry":{"type":"Polygon","coordinates":[[[-93.597531,39.240331],[-93.477039,39.295101],[-93.498947,38.944577],[-93.498947,38.928146],[-93.800178,38.9391],[-94.112364,38.917192],[-94.106887,39.141746],[-93.756363,39.20747],[-93.597531,39.240331]]]}}, -{"type":"Feature","id":"29109","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-94.008302,37.290541],[-93.624916,37.279587],[-93.608485,37.098848],[-93.608485,36.994786],[-93.608485,36.923586],[-94.008302,36.929063],[-94.063071,36.929063],[-94.057594,37.049555],[-94.052118,37.290541],[-94.008302,37.290541]]]}}, -{"type":"Feature","id":"29111","properties":{"name":"Lewis"},"geometry":{"type":"Polygon","coordinates":[[[-91.948972,40.259042],[-91.499863,40.248088],[-91.50534,40.198796],[-91.43414,39.946857],[-91.784664,39.946857],[-91.839434,39.946857],[-91.954449,39.946857],[-91.948972,40.259042]]]}}, -{"type":"Feature","id":"29113","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-91.149339,39.229378],[-90.722138,39.223901],[-90.667368,38.933623],[-90.957646,38.873376],[-91.111001,38.895284],[-91.264355,38.993869],[-91.258878,39.141746],[-91.149339,39.229378]]]}}, -{"type":"Feature","id":"29115","properties":{"name":"Linn"},"geometry":{"type":"Polygon","coordinates":[[[-92.858145,40.039965],[-92.847191,40.039965],[-92.858145,39.700394],[-93.04436,39.705871],[-93.268915,39.705871],[-93.362023,39.968764],[-93.362023,40.034488],[-92.858145,40.039965]]]}}, -{"type":"Feature","id":"29117","properties":{"name":"Livingston"},"geometry":{"type":"Polygon","coordinates":[[[-93.362023,39.968764],[-93.268915,39.705871],[-93.279869,39.61824],[-93.422269,39.612763],[-93.756363,39.612763],[-93.756363,39.782548],[-93.76184,39.957811],[-93.362023,39.968764]]]}}, -{"type":"Feature","id":"29119","properties":{"name":"McDonald"},"geometry":{"type":"Polygon","coordinates":[[[-94.539565,36.764754],[-94.068548,36.748324],[-94.079502,36.496384],[-94.473842,36.501861],[-94.616242,36.501861],[-94.616242,36.666169],[-94.616242,36.764754],[-94.539565,36.764754]]]}}, -{"type":"Feature","id":"29121","properties":{"name":"Macon"},"geometry":{"type":"Polygon","coordinates":[[[-92.677405,40.039965],[-92.343312,40.039965],[-92.288543,39.952334],[-92.299497,39.607286],[-92.299497,39.607286],[-92.693836,39.612763],[-92.858145,39.700394],[-92.847191,40.039965],[-92.677405,40.039965]]]}}, -{"type":"Feature","id":"29123","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-90.535922,37.641065],[-90.147059,37.641065],[-90.147059,37.597249],[-90.218259,37.312448],[-90.552353,37.317925],[-90.535922,37.641065]]]}}, -{"type":"Feature","id":"29125","properties":{"name":"Maries"},"geometry":{"type":"Polygon","coordinates":[[[-91.954449,38.287344],[-91.642264,38.287344],[-91.63131,38.155897],[-92.020173,38.00802],[-92.184481,38.018974],[-92.195435,38.292821],[-91.954449,38.287344]]]}}, -{"type":"Feature","id":"29127","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-91.784664,39.946857],[-91.43414,39.946857],[-91.36294,39.760641],[-91.30817,39.683964],[-91.686079,39.683964],[-91.713464,39.656579],[-91.844911,39.656579],[-91.839434,39.946857],[-91.784664,39.946857]]]}}, -{"type":"Feature","id":"29129","properties":{"name":"Mercer"},"geometry":{"type":"Polygon","coordinates":[[[-93.526331,40.582182],[-93.372977,40.582182],[-93.3675,40.385012],[-93.3675,40.264519],[-93.76184,40.264519],[-93.772794,40.576705],[-93.559193,40.582182],[-93.526331,40.582182]]]}}, -{"type":"Feature","id":"29131","properties":{"name":"Miller"},"geometry":{"type":"Polygon","coordinates":[[[-92.611682,38.429744],[-92.496666,38.429744],[-92.195435,38.336636],[-92.195435,38.292821],[-92.184481,38.018974],[-92.359743,38.018974],[-92.403558,38.018974],[-92.693836,38.22162],[-92.622636,38.429744],[-92.611682,38.429744]]]}}, -{"type":"Feature","id":"29133","properties":{"name":"Mississippi"},"geometry":{"type":"Polygon","coordinates":[[[-89.314564,37.011217],[-89.133825,36.983832],[-89.100963,36.945493],[-89.122871,36.786662],[-89.172164,36.649739],[-89.325518,36.633308],[-89.517211,36.868816],[-89.314564,37.011217]]]}}, -{"type":"Feature","id":"29135","properties":{"name":"Moniteau"},"geometry":{"type":"Polygon","coordinates":[[[-92.463805,38.862422],[-92.392605,38.736453],[-92.496666,38.429744],[-92.611682,38.429744],[-92.622636,38.429744],[-92.841714,38.681683],[-92.496666,38.922669],[-92.463805,38.862422]]]}}, -{"type":"Feature","id":"29137","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-92.299497,39.607286],[-91.844911,39.656579],[-91.713464,39.656579],[-91.718941,39.338916],[-92.31045,39.34987],[-92.299497,39.607286],[-92.299497,39.607286]]]}}, -{"type":"Feature","id":"29139","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-91.625833,39.147223],[-91.406755,39.141746],[-91.258878,39.141746],[-91.264355,38.993869],[-91.417709,38.709068],[-91.642264,38.703591],[-91.647741,38.703591],[-91.63131,39.059592],[-91.625833,39.147223]]]}}, -{"type":"Feature","id":"29141","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-93.060791,38.692637],[-92.841714,38.681683],[-92.622636,38.429744],[-92.693836,38.22162],[-93.077222,38.259959],[-93.066268,38.528329],[-93.060791,38.692637]]]}}, -{"type":"Feature","id":"29143","properties":{"name":"New Madrid"},"geometry":{"type":"Polygon","coordinates":[[[-89.528165,36.868816],[-89.517211,36.868816],[-89.325518,36.633308],[-89.418626,36.496384],[-89.484349,36.496384],[-89.539119,36.496384],[-89.544596,36.337553],[-89.714381,36.425184],[-89.960843,36.386845],[-89.960843,36.627831],[-89.692473,36.857862],[-89.528165,36.868816]]]}}, -{"type":"Feature","id":"29145","properties":{"name":"Newton"},"geometry":{"type":"Polygon","coordinates":[[[-94.616242,37.055032],[-94.616242,37.055032],[-94.057594,37.049555],[-94.063071,36.929063],[-94.068548,36.748324],[-94.539565,36.764754],[-94.616242,36.764754],[-94.616242,37.000263],[-94.616242,37.055032]]]}}, -{"type":"Feature","id":"29147","properties":{"name":"Nodaway"},"geometry":{"type":"Polygon","coordinates":[[[-95.163936,40.576705],[-94.917474,40.576705],[-94.632673,40.571228],[-94.599812,40.385012],[-94.605288,40.127596],[-95.043444,40.127596],[-95.180367,40.264519],[-95.202275,40.576705],[-95.163936,40.576705]]]}}, -{"type":"Feature","id":"29149","properties":{"name":"Oregon"},"geometry":{"type":"Polygon","coordinates":[[[-91.658695,36.890724],[-91.220539,36.885247],[-91.116477,36.825001],[-91.127431,36.496384],[-91.406755,36.496384],[-91.450571,36.496384],[-91.450571,36.496384],[-91.669648,36.501861],[-91.658695,36.890724]]]}}, -{"type":"Feature","id":"29151","properties":{"name":"Osage"},"geometry":{"type":"Polygon","coordinates":[[[-91.647741,38.703591],[-91.642264,38.703591],[-91.642264,38.287344],[-91.954449,38.287344],[-92.195435,38.292821],[-92.195435,38.336636],[-92.009219,38.572145],[-91.647741,38.703591]]]}}, -{"type":"Feature","id":"29153","properties":{"name":"Ozark"},"geometry":{"type":"Polygon","coordinates":[[[-92.529528,36.803093],[-92.113281,36.792139],[-92.118758,36.496384],[-92.151619,36.496384],[-92.529528,36.496384],[-92.770513,36.496384],[-92.765037,36.80857],[-92.529528,36.803093]]]}}, -{"type":"Feature","id":"29155","properties":{"name":"Pemiscot"},"geometry":{"type":"Polygon","coordinates":[[[-89.714381,36.425184],[-89.544596,36.337553],[-89.62675,36.184199],[-89.730812,35.997983],[-89.960843,35.997983],[-89.960843,36.386845],[-89.714381,36.425184]]]}}, -{"type":"Feature","id":"29157","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-89.938935,37.876573],[-89.676042,37.805373],[-89.522688,37.569865],[-89.522688,37.564388],[-89.796535,37.602726],[-89.862258,37.597249],[-90.147059,37.597249],[-90.147059,37.641065],[-90.10872,37.673926],[-89.938935,37.876573]]]}}, -{"type":"Feature","id":"29159","properties":{"name":"Pettis"},"geometry":{"type":"Polygon","coordinates":[[[-93.498947,38.944577],[-93.049837,38.928146],[-93.060791,38.692637],[-93.066268,38.528329],[-93.159376,38.533806],[-93.515377,38.511898],[-93.5099,38.555714],[-93.498947,38.928146],[-93.498947,38.944577]]]}}, -{"type":"Feature","id":"29161","properties":{"name":"Phelps"},"geometry":{"type":"Polygon","coordinates":[[[-91.63131,38.155897],[-91.532725,38.15042],[-91.527248,37.788942],[-91.806572,37.597249],[-92.031127,37.602726],[-92.020173,38.00802],[-91.63131,38.155897]]]}}, -{"type":"Feature","id":"29163","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-91.198632,39.596333],[-91.176724,39.596333],[-90.935738,39.399163],[-90.722138,39.223901],[-91.149339,39.229378],[-91.258878,39.141746],[-91.406755,39.141746],[-91.439617,39.317009],[-91.198632,39.596333]]]}}, -{"type":"Feature","id":"29165","properties":{"name":"Platte"},"geometry":{"type":"Polygon","coordinates":[[[-95.10369,39.530609],[-94.599812,39.530609],[-94.599812,39.453932],[-94.599812,39.158177],[-94.775074,39.201993],[-94.966767,39.42107],[-95.10369,39.530609]]]}}, -{"type":"Feature","id":"29167","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-93.630393,37.827281],[-93.575624,37.827281],[-93.186761,37.805373],[-93.181284,37.41651],[-93.619439,37.427464],[-93.613962,37.575342],[-93.630393,37.827281]]]}}, -{"type":"Feature","id":"29169","properties":{"name":"Pulaski"},"geometry":{"type":"Polygon","coordinates":[[[-92.359743,38.018974],[-92.184481,38.018974],[-92.020173,38.00802],[-92.031127,37.602726],[-92.250204,37.602726],[-92.409035,37.860142],[-92.403558,38.018974],[-92.359743,38.018974]]]}}, -{"type":"Feature","id":"29171","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-92.748606,40.587659],[-92.715744,40.587659],[-92.682882,40.341196],[-92.858145,40.341196],[-93.186761,40.385012],[-93.3675,40.385012],[-93.372977,40.582182],[-93.09913,40.582182],[-92.748606,40.587659]]]}}, -{"type":"Feature","id":"29173","properties":{"name":"Ralls"},"geometry":{"type":"Polygon","coordinates":[[[-91.686079,39.683964],[-91.30817,39.683964],[-91.176724,39.596333],[-91.198632,39.596333],[-91.439617,39.317009],[-91.718941,39.338916],[-91.713464,39.656579],[-91.686079,39.683964]]]}}, -{"type":"Feature","id":"29175","properties":{"name":"Randolph"},"geometry":{"type":"Polygon","coordinates":[[[-92.693836,39.612763],[-92.299497,39.607286],[-92.31045,39.34987],[-92.315927,39.245808],[-92.430943,39.251285],[-92.70479,39.322485],[-92.693836,39.612763]]]}}, -{"type":"Feature","id":"29177","properties":{"name":"Ray"},"geometry":{"type":"Polygon","coordinates":[[[-94.10141,39.525132],[-93.76184,39.525132],[-93.756363,39.20747],[-94.106887,39.141746],[-94.210949,39.20747],[-94.210949,39.453932],[-94.210949,39.525132],[-94.10141,39.525132]]]}}, -{"type":"Feature","id":"29179","properties":{"name":"Reynolds"},"geometry":{"type":"Polygon","coordinates":[[[-90.77143,37.476757],[-90.733092,37.268633],[-90.776907,37.049555],[-91.017893,37.093371],[-91.209585,37.41651],[-91.154816,37.586295],[-90.77143,37.476757]]]}}, -{"type":"Feature","id":"29181","properties":{"name":"Ripley"},"geometry":{"type":"Polygon","coordinates":[[[-90.935738,36.814047],[-90.661891,36.814047],[-90.57426,36.496384],[-90.782384,36.496384],[-90.848107,36.496384],[-91.127431,36.496384],[-91.116477,36.825001],[-90.935738,36.814047]]]}}, -{"type":"Feature","id":"29183","properties":{"name":"St. Charles"},"geometry":{"type":"Polygon","coordinates":[[[-90.448291,38.966484],[-90.278506,38.922669],[-90.119674,38.807653],[-90.283983,38.878853],[-90.733092,38.637868],[-90.963123,38.550237],[-90.957646,38.873376],[-90.667368,38.933623],[-90.448291,38.966484]]]}}, -{"type":"Feature","id":"29185","properties":{"name":"St. Clair"},"geometry":{"type":"Polygon","coordinates":[[[-93.772794,38.20519],[-93.520854,38.20519],[-93.504423,38.073743],[-93.575624,37.827281],[-93.630393,37.827281],[-94.063071,37.898481],[-94.057594,38.035405],[-94.052118,38.216144],[-93.772794,38.20519]]]}}, -{"type":"Feature","id":"29186","properties":{"name":"Ste. Genevieve"},"geometry":{"type":"Polygon","coordinates":[[[-90.251121,38.128512],[-90.207305,38.090174],[-89.938935,37.876573],[-90.10872,37.673926],[-90.415429,38.040881],[-90.251121,38.128512]]]}}, -{"type":"Feature","id":"29187","properties":{"name":"St. Francois"},"geometry":{"type":"Polygon","coordinates":[[[-90.639984,38.07922],[-90.415429,38.040881],[-90.10872,37.673926],[-90.147059,37.641065],[-90.535922,37.641065],[-90.645461,37.734173],[-90.639984,38.07922]]]}}, -{"type":"Feature","id":"29189","properties":{"name":"St. Louis"},"geometry":{"type":"Polygon","coordinates":[[[-90.283983,38.878853],[-90.119674,38.807653],[-90.168967,38.774791],[-90.256598,38.533806],[-90.262075,38.522852],[-90.344229,38.385929],[-90.464722,38.500944],[-90.738569,38.47356],[-90.733092,38.637868],[-90.283983,38.878853]]]}}, -{"type":"Feature","id":"29195","properties":{"name":"Saline"},"geometry":{"type":"Polygon","coordinates":[[[-93.274392,39.317009],[-93.104607,39.382732],[-92.847191,39.223901],[-92.934822,39.065069],[-93.049837,38.928146],[-93.498947,38.944577],[-93.477039,39.295101],[-93.274392,39.317009]]]}}, -{"type":"Feature","id":"29197","properties":{"name":"Schuyler"},"geometry":{"type":"Polygon","coordinates":[[[-92.452851,40.593136],[-92.348789,40.598613],[-92.348789,40.346673],[-92.682882,40.341196],[-92.715744,40.587659],[-92.639067,40.593136],[-92.452851,40.593136]]]}}, -{"type":"Feature","id":"29199","properties":{"name":"Scotland"},"geometry":{"type":"Polygon","coordinates":[[[-91.943495,40.60409],[-91.948972,40.302858],[-92.140665,40.302858],[-92.348789,40.302858],[-92.348789,40.346673],[-92.348789,40.598613],[-92.179004,40.598613],[-91.943495,40.60409]]]}}, -{"type":"Feature","id":"29201","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-89.489826,37.252202],[-89.314564,37.011217],[-89.517211,36.868816],[-89.528165,36.868816],[-89.692473,36.857862],[-89.763673,37.126232],[-89.489826,37.252202]]]}}, -{"type":"Feature","id":"29203","properties":{"name":"Shannon"},"geometry":{"type":"Polygon","coordinates":[[[-91.554633,37.421987],[-91.209585,37.41651],[-91.017893,37.093371],[-91.220539,37.038601],[-91.220539,36.885247],[-91.658695,36.890724],[-91.653218,37.049555],[-91.647741,37.421987],[-91.554633,37.421987]]]}}, -{"type":"Feature","id":"29205","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-91.998265,39.952334],[-91.954449,39.946857],[-91.839434,39.946857],[-91.844911,39.656579],[-92.299497,39.607286],[-92.288543,39.952334],[-91.998265,39.952334]]]}}, -{"type":"Feature","id":"29207","properties":{"name":"Stoddard"},"geometry":{"type":"Polygon","coordinates":[[[-89.867735,37.126232],[-89.763673,37.126232],[-89.692473,36.857862],[-89.960843,36.627831],[-90.048474,36.627831],[-90.147059,36.633308],[-90.256598,36.923586],[-90.10872,37.038601],[-89.867735,37.126232],[-89.867735,37.126232]]]}}, -{"type":"Feature","id":"29209","properties":{"name":"Stone"},"geometry":{"type":"Polygon","coordinates":[[[-93.592055,36.994786],[-93.301777,36.819524],[-93.312731,36.496384],[-93.586578,36.496384],[-93.608485,36.923586],[-93.608485,36.994786],[-93.592055,36.994786]]]}}, -{"type":"Feature","id":"29211","properties":{"name":"Sullivan"},"geometry":{"type":"Polygon","coordinates":[[[-93.186761,40.385012],[-92.858145,40.341196],[-92.858145,40.039965],[-93.362023,40.034488],[-93.3675,40.264519],[-93.3675,40.385012],[-93.186761,40.385012]]]}}, -{"type":"Feature","id":"29213","properties":{"name":"Taney"},"geometry":{"type":"Polygon","coordinates":[[[-93.301777,36.819524],[-92.907437,36.80857],[-92.765037,36.80857],[-92.770513,36.496384],[-92.852668,36.496384],[-93.066268,36.496384],[-93.2963,36.496384],[-93.312731,36.496384],[-93.301777,36.819524]]]}}, -{"type":"Feature","id":"29215","properties":{"name":"Texas"},"geometry":{"type":"Polygon","coordinates":[[[-92.250204,37.602726],[-92.031127,37.602726],[-91.806572,37.597249],[-91.647741,37.421987],[-91.653218,37.049555],[-92.074942,37.055032],[-92.091373,37.055032],[-92.250204,37.060509],[-92.250204,37.47128],[-92.250204,37.602726]]]}}, -{"type":"Feature","id":"29217","properties":{"name":"Vernon"},"geometry":{"type":"Polygon","coordinates":[[[-94.501227,38.057312],[-94.057594,38.035405],[-94.063071,37.898481],[-94.074025,37.641065],[-94.490273,37.652019],[-94.616242,37.652019],[-94.616242,37.673926],[-94.616242,38.035405],[-94.616242,38.062789],[-94.501227,38.057312]]]}}, -{"type":"Feature","id":"29219","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-91.111001,38.895284],[-90.957646,38.873376],[-90.963123,38.550237],[-91.368417,38.698114],[-91.417709,38.709068],[-91.264355,38.993869],[-91.111001,38.895284]]]}}, -{"type":"Feature","id":"29221","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-91.09457,38.20519],[-90.782384,38.20519],[-90.639984,38.07922],[-90.645461,37.734173],[-91.100047,37.73965],[-91.09457,38.20519]]]}}, -{"type":"Feature","id":"29223","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-90.552353,37.317925],[-90.218259,37.312448],[-90.10872,37.038601],[-90.256598,36.923586],[-90.568783,36.929063],[-90.678322,36.929063],[-90.776907,37.049555],[-90.733092,37.268633],[-90.552353,37.317925]]]}}, -{"type":"Feature","id":"29225","properties":{"name":"Webster"},"geometry":{"type":"Polygon","coordinates":[[[-93.071745,37.48771],[-92.852668,37.482234],[-92.688359,37.482234],[-92.688359,37.065986],[-92.90196,37.071463],[-93.066268,37.087894],[-93.071745,37.41651],[-93.071745,37.48771]]]}}, -{"type":"Feature","id":"29227","properties":{"name":"Worth"},"geometry":{"type":"Polygon","coordinates":[[[-94.287626,40.571228],[-94.232857,40.571228],[-94.216426,40.385012],[-94.325965,40.385012],[-94.599812,40.385012],[-94.632673,40.571228],[-94.473842,40.571228],[-94.287626,40.571228]]]}}, -{"type":"Feature","id":"29229","properties":{"name":"Wright"},"geometry":{"type":"Polygon","coordinates":[[[-92.688359,37.482234],[-92.250204,37.47128],[-92.250204,37.060509],[-92.688359,37.065986],[-92.688359,37.482234]]]}}, -{"type":"Feature","id":"29510","properties":{"name":"St. Louis"},"geometry":{"type":"Polygon","coordinates":[[[-90.168967,38.774791],[-90.179921,38.659776],[-90.256598,38.533806],[-90.168967,38.774791]]]}}, -{"type":"Feature","id":"30001","properties":{"name":"Beaverhead"},"geometry":{"type":"Polygon","coordinates":[[[-113.517164,45.938629],[-113.084485,45.861952],[-112.684669,45.626444],[-112.169836,44.826811],[-111.479742,44.711795],[-111.616665,44.547487],[-112.816115,44.377701],[-113.456917,44.865149],[-113.944365,45.68669],[-113.517164,45.938629]]]}}, -{"type":"Feature","id":"30003","properties":{"name":"Big Horn"},"geometry":{"type":"Polygon","coordinates":[[[-107.426806,45.976968],[-106.939358,45.867429],[-106.769573,45.177335],[-106.282125,45.177335],[-106.265695,44.991119],[-107.914254,45.002073],[-108.248347,45.002073],[-108.642687,45.462136],[-108.067608,45.516905],[-108.0457,45.900291],[-107.50896,46.042691],[-107.426806,45.976968]]]}}, -{"type":"Feature","id":"30005","properties":{"name":"Blaine"},"geometry":{"type":"Polygon","coordinates":[[[-108.237393,49.000239],[-108.434563,47.976051],[-108.889149,47.735066],[-109.540905,47.740543],[-109.535428,48.134883],[-109.491612,49.000239],[-108.237393,49.000239]]]}}, -{"type":"Feature","id":"30007","properties":{"name":"Broadwater"},"geometry":{"type":"Polygon","coordinates":[[[-111.638573,46.716355],[-111.496173,46.760171],[-111.063494,46.190569],[-111.660481,45.834568],[-111.78645,46.568478],[-111.638573,46.716355]]]}}, -{"type":"Feature","id":"30009","properties":{"name":"Carbon"},"geometry":{"type":"Polygon","coordinates":[[[-108.806995,45.626444],[-108.642687,45.462136],[-108.248347,45.002073],[-108.620779,45.002073],[-109.798321,45.002073],[-109.798321,45.166381],[-108.845333,45.610013],[-108.806995,45.626444]]]}}, -{"type":"Feature","id":"30011","properties":{"name":"Carter"},"geometry":{"type":"Polygon","coordinates":[[[-104.885506,46.135799],[-104.042057,45.88386],[-104.042057,45.210196],[-104.058488,44.996596],[-105.03886,45.002073],[-104.98409,45.785275],[-104.885506,46.135799]]]}}, -{"type":"Feature","id":"30013","properties":{"name":"Cascade"},"geometry":{"type":"Polygon","coordinates":[[[-111.419495,47.696727],[-111.408542,47.696727],[-110.64177,47.417403],[-110.652724,46.825894],[-111.079925,47.088787],[-111.660481,46.913525],[-112.049344,47.515988],[-111.419495,47.696727]]]}}, -{"type":"Feature","id":"30015","properties":{"name":"Chouteau"},"geometry":{"type":"Polygon","coordinates":[[[-110.389831,48.304668],[-109.535428,48.134883],[-109.540905,47.740543],[-110.214569,47.417403],[-110.504846,47.417403],[-110.64177,47.417403],[-111.408542,47.696727],[-111.408542,47.987005],[-111.408542,48.129406],[-110.756786,48.217037],[-110.389831,48.304668]]]}}, -{"type":"Feature","id":"30017","properties":{"name":"Custer"},"geometry":{"type":"Polygon","coordinates":[[[-106.084956,46.858755],[-105.44963,46.568478],[-104.732151,46.612293],[-104.885506,46.135799],[-104.98409,45.785275],[-106.128771,45.790752],[-106.194494,45.790752],[-106.084956,46.847802],[-106.084956,46.858755]]]}}, -{"type":"Feature","id":"30019","properties":{"name":"Daniels"},"geometry":{"type":"Polygon","coordinates":[[[-105.055291,49.000239],[-104.973137,48.562084],[-105.756339,48.562084],[-105.805632,48.562084],[-106.11234,49.000239],[-105.055291,49.000239]]]}}, -{"type":"Feature","id":"30021","properties":{"name":"Dawson"},"geometry":{"type":"Polygon","coordinates":[[[-105.022429,47.702204],[-104.419966,47.357157],[-104.606182,46.858755],[-105.405815,47.181895],[-105.23603,47.789835],[-105.022429,47.702204]]]}}, -{"type":"Feature","id":"30023","properties":{"name":"Deer Lodge"},"geometry":{"type":"Polygon","coordinates":[[[-112.887315,46.267246],[-112.558699,46.267246],[-112.57513,46.179615],[-113.084485,45.861952],[-113.517164,45.938629],[-113.517164,45.938629],[-113.035193,46.267246],[-112.887315,46.267246]]]}}, -{"type":"Feature","id":"30025","properties":{"name":"Fallon"},"geometry":{"type":"Polygon","coordinates":[[[-104.732151,46.612293],[-104.606182,46.683493],[-104.047534,46.639678],[-104.047534,46.541093],[-104.047534,46.2782],[-104.047534,45.944106],[-104.042057,45.88386],[-104.885506,46.135799],[-104.732151,46.612293]]]}}, -{"type":"Feature","id":"30027","properties":{"name":"Fergus"},"geometry":{"type":"Polygon","coordinates":[[[-110.214569,47.417403],[-109.540905,47.740543],[-108.889149,47.735066],[-108.31407,47.581712],[-108.719364,47.269526],[-108.631733,46.749217],[-109.009642,46.749217],[-109.387551,46.694447],[-109.743552,46.694447],[-109.754506,47.187372],[-110.214569,47.417403]]]}}, -{"type":"Feature","id":"30029","properties":{"name":"Flathead"},"geometry":{"type":"Polygon","coordinates":[[[-114.070335,49.000239],[-113.347378,48.310145],[-113.018762,48.134883],[-112.9859,47.954144],[-113.144732,47.598142],[-113.467871,47.598142],[-113.632179,47.598142],[-114.010088,48.052728],[-114.601598,47.789835],[-115.012368,48.019867],[-114.727567,49.000239],[-114.070335,49.000239]]]}}, -{"type":"Feature","id":"30031","properties":{"name":"Gallatin"},"geometry":{"type":"Polygon","coordinates":[[[-111.063494,46.190569],[-110.78417,46.190569],[-111.041587,45.002073],[-111.058017,44.667979],[-111.047063,44.476286],[-111.37568,44.750133],[-111.353772,45.642875],[-111.802881,45.796229],[-111.660481,45.834568],[-111.063494,46.190569]]]}}, -{"type":"Feature","id":"30033","properties":{"name":"Garfield"},"geometry":{"type":"Polygon","coordinates":[[[-106.490249,47.95962],[-106.419049,47.95962],[-106.084956,47.181895],[-106.084956,46.858755],[-106.084956,46.847802],[-107.459668,46.858755],[-107.892346,46.853278],[-107.908777,47.450265],[-107.415852,47.69125],[-106.490249,47.95962]]]}}, -{"type":"Feature","id":"30035","properties":{"name":"Glacier"},"geometry":{"type":"Polygon","coordinates":[[[-112.191744,49.000239],[-112.186267,48.47993],[-112.57513,48.485407],[-113.347378,48.310145],[-114.070335,49.000239],[-112.191744,49.000239]]]}}, -{"type":"Feature","id":"30037","properties":{"name":"Golden Valley"},"geometry":{"type":"Polygon","coordinates":[[[-109.387551,46.694447],[-109.009642,46.749217],[-108.77961,46.130322],[-108.922011,46.130322],[-109.17395,46.130322],[-109.414935,46.042691],[-109.655921,46.217953],[-109.387551,46.694447]]]}}, -{"type":"Feature","id":"30039","properties":{"name":"Granite"},"geometry":{"type":"Polygon","coordinates":[[[-113.303563,46.831371],[-113.035193,46.267246],[-113.517164,45.938629],[-113.801964,46.037214],[-113.829349,46.661586],[-113.303563,46.831371]]]}}, -{"type":"Feature","id":"30041","properties":{"name":"Hill"},"geometry":{"type":"Polygon","coordinates":[[[-109.491612,49.000239],[-109.535428,48.134883],[-110.389831,48.304668],[-110.756786,48.217037],[-110.745832,49.000239],[-109.491612,49.000239]]]}}, -{"type":"Feature","id":"30043","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-111.967189,46.568478],[-111.78645,46.568478],[-111.660481,45.834568],[-111.802881,45.796229],[-111.967189,45.850998],[-112.191744,45.746937],[-112.57513,46.179615],[-112.558699,46.267246],[-112.312237,46.4206],[-111.967189,46.568478]]]}}, -{"type":"Feature","id":"30045","properties":{"name":"Judith Basin"},"geometry":{"type":"Polygon","coordinates":[[[-110.504846,47.417403],[-110.214569,47.417403],[-109.754506,47.187372],[-109.743552,46.694447],[-110.148845,46.716355],[-110.274815,46.710878],[-110.652724,46.825894],[-110.64177,47.417403],[-110.504846,47.417403]]]}}, -{"type":"Feature","id":"30047","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-114.010088,48.052728],[-113.632179,47.598142],[-113.91698,47.499557],[-114.18535,47.138079],[-114.601598,47.789835],[-114.010088,48.052728]]]}}, -{"type":"Feature","id":"30049","properties":{"name":"Lewis and Clark"},"geometry":{"type":"Polygon","coordinates":[[[-112.9859,47.954144],[-112.816115,47.609096],[-112.049344,47.515988],[-111.660481,46.913525],[-111.496173,46.760171],[-111.638573,46.716355],[-111.78645,46.568478],[-111.967189,46.568478],[-112.312237,46.4206],[-112.794207,46.831371],[-113.144732,47.598142],[-112.9859,47.954144]]]}}, -{"type":"Feature","id":"30051","properties":{"name":"Liberty"},"geometry":{"type":"Polygon","coordinates":[[[-110.745832,49.000239],[-110.756786,48.217037],[-111.408542,48.129406],[-111.408542,48.217037],[-111.271618,48.994762],[-110.745832,49.000239]]]}}, -{"type":"Feature","id":"30053","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-114.727567,49.000239],[-115.012368,48.019867],[-115.521724,47.910328],[-115.844863,48.21156],[-116.04751,48.217037],[-116.04751,48.501838],[-116.04751,49.000239],[-114.727567,49.000239]]]}}, -{"type":"Feature","id":"30055","properties":{"name":"McCone"},"geometry":{"type":"Polygon","coordinates":[[[-105.192214,48.063682],[-105.23603,47.789835],[-105.405815,47.181895],[-105.789201,47.181895],[-106.084956,47.181895],[-106.419049,47.95962],[-105.84397,48.008913],[-105.192214,48.063682]]]}}, -{"type":"Feature","id":"30057","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-111.967189,45.850998],[-111.802881,45.796229],[-111.353772,45.642875],[-111.37568,44.750133],[-111.479742,44.711795],[-112.169836,44.826811],[-112.684669,45.626444],[-112.191744,45.746937],[-111.967189,45.850998]]]}}, -{"type":"Feature","id":"30059","properties":{"name":"Meagher"},"geometry":{"type":"Polygon","coordinates":[[[-111.079925,47.088787],[-110.652724,46.825894],[-110.274815,46.710878],[-110.280292,46.217953],[-110.280292,46.185092],[-110.78417,46.190569],[-111.063494,46.190569],[-111.496173,46.760171],[-111.660481,46.913525],[-111.079925,47.088787]]]}}, -{"type":"Feature","id":"30061","properties":{"name":"Mineral"},"geometry":{"type":"Polygon","coordinates":[[[-115.499816,47.488604],[-114.798768,47.269526],[-114.672798,46.738263],[-114.963076,46.935433],[-115.658647,47.466696],[-115.499816,47.488604]]]}}, -{"type":"Feature","id":"30063","properties":{"name":"Missoula"},"geometry":{"type":"Polygon","coordinates":[[[-113.91698,47.499557],[-113.632179,47.598142],[-113.467871,47.598142],[-113.303563,46.831371],[-113.829349,46.661586],[-113.851257,46.661586],[-114.333228,46.661586],[-114.596121,46.634201],[-114.672798,46.738263],[-114.798768,47.269526],[-114.18535,47.138079],[-113.91698,47.499557]]]}}, -{"type":"Feature","id":"30065","properties":{"name":"Musselshell"},"geometry":{"type":"Polygon","coordinates":[[[-107.837576,46.754694],[-107.826623,46.754694],[-107.782807,46.497277],[-108.77961,46.130322],[-109.009642,46.749217],[-108.631733,46.749217],[-107.837576,46.754694]]]}}, -{"type":"Feature","id":"30067","properties":{"name":"Park"},"geometry":{"type":"Polygon","coordinates":[[[-110.78417,46.190569],[-110.280292,46.185092],[-110.230999,45.171858],[-110.061214,45.171858],[-109.798321,45.166381],[-109.798321,45.002073],[-111.041587,45.002073],[-110.78417,46.190569]]]}}, -{"type":"Feature","id":"30069","properties":{"name":"Petroleum"},"geometry":{"type":"Polygon","coordinates":[[[-108.105947,47.592665],[-107.908777,47.450265],[-107.892346,46.853278],[-107.826623,46.754694],[-107.837576,46.754694],[-108.631733,46.749217],[-108.719364,47.269526],[-108.31407,47.581712],[-108.105947,47.592665]]]}}, -{"type":"Feature","id":"30071","properties":{"name":"Phillips"},"geometry":{"type":"Polygon","coordinates":[[[-107.180344,49.000239],[-107.415852,47.69125],[-107.908777,47.450265],[-108.105947,47.592665],[-108.31407,47.581712],[-108.889149,47.735066],[-108.434563,47.976051],[-108.237393,49.000239],[-107.180344,49.000239]]]}}, -{"type":"Feature","id":"30073","properties":{"name":"Pondera"},"geometry":{"type":"Polygon","coordinates":[[[-112.57513,48.485407],[-112.186267,48.47993],[-111.408542,48.217037],[-111.408542,48.129406],[-111.408542,47.987005],[-112.898269,48.134883],[-113.018762,48.134883],[-113.347378,48.310145],[-112.57513,48.485407]]]}}, -{"type":"Feature","id":"30075","properties":{"name":"Powder River"},"geometry":{"type":"Polygon","coordinates":[[[-106.128771,45.790752],[-104.98409,45.785275],[-105.03886,45.002073],[-105.088152,45.002073],[-106.024709,44.991119],[-106.265695,44.991119],[-106.282125,45.177335],[-106.194494,45.790752],[-106.128771,45.790752]]]}}, -{"type":"Feature","id":"30077","properties":{"name":"Powell"},"geometry":{"type":"Polygon","coordinates":[[[-113.467871,47.598142],[-113.144732,47.598142],[-112.794207,46.831371],[-112.312237,46.4206],[-112.558699,46.267246],[-112.887315,46.267246],[-113.035193,46.267246],[-113.303563,46.831371],[-113.467871,47.598142]]]}}, -{"type":"Feature","id":"30079","properties":{"name":"Prairie"},"geometry":{"type":"Polygon","coordinates":[[[-105.789201,47.181895],[-105.405815,47.181895],[-104.606182,46.858755],[-104.606182,46.683493],[-104.732151,46.612293],[-105.44963,46.568478],[-106.084956,46.858755],[-106.084956,47.181895],[-105.789201,47.181895]]]}}, -{"type":"Feature","id":"30081","properties":{"name":"Ravalli"},"geometry":{"type":"Polygon","coordinates":[[[-113.851257,46.661586],[-113.829349,46.661586],[-113.801964,46.037214],[-113.517164,45.938629],[-113.517164,45.938629],[-113.944365,45.68669],[-114.557782,45.566198],[-114.333228,46.661586],[-113.851257,46.661586]]]}}, -{"type":"Feature","id":"30083","properties":{"name":"Richland"},"geometry":{"type":"Polygon","coordinates":[[[-104.567843,48.118452],[-104.042057,47.997959],[-104.047534,47.395496],[-104.419966,47.357157],[-105.022429,47.702204],[-105.23603,47.789835],[-105.192214,48.063682],[-104.567843,48.118452]]]}}, -{"type":"Feature","id":"30085","properties":{"name":"Roosevelt"},"geometry":{"type":"Polygon","coordinates":[[[-105.756339,48.562084],[-104.973137,48.562084],[-104.047534,48.386822],[-104.042057,47.997959],[-104.567843,48.118452],[-105.192214,48.063682],[-105.84397,48.008913],[-105.805632,48.562084],[-105.756339,48.562084]]]}}, -{"type":"Feature","id":"30087","properties":{"name":"Rosebud"},"geometry":{"type":"Polygon","coordinates":[[[-107.459668,46.858755],[-106.084956,46.847802],[-106.194494,45.790752],[-106.282125,45.177335],[-106.769573,45.177335],[-106.939358,45.867429],[-107.026989,46.393216],[-107.738991,46.480847],[-107.782807,46.497277],[-107.826623,46.754694],[-107.892346,46.853278],[-107.459668,46.858755]]]}}, -{"type":"Feature","id":"30089","properties":{"name":"Sanders"},"geometry":{"type":"Polygon","coordinates":[[[-115.844863,48.21156],[-115.521724,47.910328],[-115.012368,48.019867],[-114.601598,47.789835],[-114.18535,47.138079],[-114.798768,47.269526],[-115.499816,47.488604],[-115.658647,47.466696],[-116.04751,47.976051],[-116.04751,48.217037],[-115.844863,48.21156]]]}}, -{"type":"Feature","id":"30091","properties":{"name":"Sheridan"},"geometry":{"type":"Polygon","coordinates":[[[-104.047534,49.000239],[-104.047534,48.633284],[-104.047534,48.386822],[-104.973137,48.562084],[-105.055291,49.000239],[-104.047534,49.000239]]]}}, -{"type":"Feature","id":"30093","properties":{"name":"Silver Bow"},"geometry":{"type":"Polygon","coordinates":[[[-112.57513,46.179615],[-112.191744,45.746937],[-112.684669,45.626444],[-113.084485,45.861952],[-112.57513,46.179615]]]}}, -{"type":"Feature","id":"30095","properties":{"name":"Stillwater"},"geometry":{"type":"Polygon","coordinates":[[[-109.17395,46.130322],[-108.922011,46.130322],[-108.845333,45.610013],[-109.798321,45.166381],[-110.061214,45.171858],[-109.562813,45.610013],[-109.414935,46.042691],[-109.17395,46.130322]]]}}, -{"type":"Feature","id":"30097","properties":{"name":"Sweet Grass"},"geometry":{"type":"Polygon","coordinates":[[[-110.006445,46.217953],[-109.655921,46.217953],[-109.414935,46.042691],[-109.562813,45.610013],[-110.061214,45.171858],[-110.230999,45.171858],[-110.280292,46.185092],[-110.280292,46.217953],[-110.006445,46.217953]]]}}, -{"type":"Feature","id":"30099","properties":{"name":"Teton"},"geometry":{"type":"Polygon","coordinates":[[[-112.898269,48.134883],[-111.408542,47.987005],[-111.408542,47.696727],[-111.419495,47.696727],[-112.049344,47.515988],[-112.816115,47.609096],[-112.9859,47.954144],[-113.018762,48.134883],[-112.898269,48.134883]]]}}, -{"type":"Feature","id":"30101","properties":{"name":"Toole"},"geometry":{"type":"Polygon","coordinates":[[[-111.271618,48.994762],[-111.408542,48.217037],[-112.186267,48.47993],[-112.191744,49.000239],[-111.271618,48.994762]]]}}, -{"type":"Feature","id":"30103","properties":{"name":"Treasure"},"geometry":{"type":"Polygon","coordinates":[[[-107.738991,46.480847],[-107.026989,46.393216],[-106.939358,45.867429],[-107.426806,45.976968],[-107.50896,46.042691],[-107.738991,46.480847]]]}}, -{"type":"Feature","id":"30105","properties":{"name":"Valley"},"geometry":{"type":"Polygon","coordinates":[[[-106.11234,49.000239],[-105.805632,48.562084],[-105.84397,48.008913],[-106.419049,47.95962],[-106.490249,47.95962],[-107.415852,47.69125],[-107.180344,49.000239],[-106.11234,49.000239]]]}}, -{"type":"Feature","id":"30107","properties":{"name":"Wheatland"},"geometry":{"type":"Polygon","coordinates":[[[-110.148845,46.716355],[-109.743552,46.694447],[-109.387551,46.694447],[-109.655921,46.217953],[-110.006445,46.217953],[-110.280292,46.217953],[-110.274815,46.710878],[-110.148845,46.716355]]]}}, -{"type":"Feature","id":"30109","properties":{"name":"Wibaux"},"geometry":{"type":"Polygon","coordinates":[[[-104.047534,47.395496],[-104.047534,47.329772],[-104.047534,46.639678],[-104.606182,46.683493],[-104.606182,46.858755],[-104.419966,47.357157],[-104.047534,47.395496]]]}}, -{"type":"Feature","id":"30111","properties":{"name":"Yellowstone"},"geometry":{"type":"Polygon","coordinates":[[[-107.782807,46.497277],[-107.738991,46.480847],[-107.50896,46.042691],[-108.0457,45.900291],[-108.067608,45.516905],[-108.642687,45.462136],[-108.806995,45.626444],[-108.845333,45.610013],[-108.922011,46.130322],[-108.77961,46.130322],[-107.782807,46.497277]]]}}, -{"type":"Feature","id":"31001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-98.723948,40.697198],[-98.280315,40.697198],[-98.280315,40.697198],[-98.280315,40.35215],[-98.291269,40.35215],[-98.723948,40.35215],[-98.723948,40.691721],[-98.723948,40.697198]]]}}, -{"type":"Feature","id":"31003","properties":{"name":"Antelope"},"geometry":{"type":"Polygon","coordinates":[[[-97.836683,42.438865],[-97.836683,42.08834],[-97.831206,41.918555],[-97.91336,41.918555],[-98.296746,41.913078],[-98.302223,42.08834],[-98.302223,42.438865],[-97.836683,42.438865]]]}}, -{"type":"Feature","id":"31005","properties":{"name":"Arthur"},"geometry":{"type":"Polygon","coordinates":[[[-101.424079,41.743293],[-101.407648,41.743293],[-101.407648,41.392769],[-101.982727,41.392769],[-101.988204,41.743293],[-101.424079,41.743293]]]}}, -{"type":"Feature","id":"31007","properties":{"name":"Banner"},"geometry":{"type":"Polygon","coordinates":[[[-104.053011,41.699478],[-103.368393,41.699478],[-103.368393,41.436584],[-103.379347,41.392769],[-104.053011,41.392769],[-104.053011,41.562554],[-104.053011,41.699478]]]}}, -{"type":"Feature","id":"31009","properties":{"name":"Blaine"},"geometry":{"type":"Polygon","coordinates":[[[-100.268445,42.08834],[-100.16986,42.08834],[-99.687889,42.08834],[-99.687889,41.737816],[-100.252014,41.737816],[-100.262968,41.737816],[-100.268445,42.08834]]]}}, -{"type":"Feature","id":"31011","properties":{"name":"Boone"},"geometry":{"type":"Polygon","coordinates":[[[-97.91336,41.918555],[-97.831206,41.918555],[-97.831206,41.743293],[-97.831206,41.524216],[-98.291269,41.4804],[-98.296746,41.743293],[-98.296746,41.913078],[-97.91336,41.918555]]]}}, -{"type":"Feature","id":"31013","properties":{"name":"Box Butte"},"geometry":{"type":"Polygon","coordinates":[[[-102.771407,42.438865],[-102.700206,42.006186],[-103.362916,42.000709],[-103.401255,42.006186],[-103.44507,42.438865],[-102.771407,42.438865]]]}}, -{"type":"Feature","id":"31015","properties":{"name":"Boyd"},"geometry":{"type":"Polygon","coordinates":[[[-98.499393,42.997512],[-98.3077,42.882497],[-98.3077,42.762004],[-98.997795,42.887974],[-99.255211,42.80582],[-99.255211,42.997512],[-98.499393,42.997512]]]}}, -{"type":"Feature","id":"31017","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-100.175337,42.833204],[-99.676935,42.729142],[-99.660504,42.08834],[-99.687889,42.08834],[-100.16986,42.08834],[-100.197245,42.844158],[-100.175337,42.833204]]]}}, -{"type":"Feature","id":"31019","properties":{"name":"Buffalo"},"geometry":{"type":"Polygon","coordinates":[[[-99.052564,41.047722],[-98.745855,41.047722],[-98.723948,41.047722],[-98.723948,40.697198],[-98.723948,40.691721],[-98.953979,40.653382],[-99.178534,40.658859],[-99.419519,40.669813],[-99.424996,41.047722],[-99.205918,41.047722],[-99.052564,41.047722]]]}}, -{"type":"Feature","id":"31021","properties":{"name":"Burt"},"geometry":{"type":"Polygon","coordinates":[[[-96.270278,42.044525],[-96.138832,41.863786],[-96.122401,41.683047],[-96.407202,41.683047],[-96.44554,41.683047],[-96.555079,41.743293],[-96.555079,42.01714],[-96.270278,42.044525]]]}}, -{"type":"Feature","id":"31023","properties":{"name":"Butler"},"geometry":{"type":"Polygon","coordinates":[[[-96.905603,41.453015],[-96.905603,41.453015],[-96.91108,41.047722],[-96.91108,41.047722],[-97.349236,41.047722],[-97.365666,41.047722],[-97.365666,41.392769],[-97.256128,41.376338],[-96.905603,41.453015]]]}}, -{"type":"Feature","id":"31025","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-96.040247,41.064153],[-95.881416,41.053199],[-95.815692,40.899844],[-95.832123,40.784829],[-95.892369,40.784829],[-96.461971,40.784829],[-96.461971,41.01486],[-96.319571,41.047722],[-96.040247,41.064153]]]}}, -{"type":"Feature","id":"31027","properties":{"name":"Cedar"},"geometry":{"type":"Polygon","coordinates":[[[-97.486159,42.849635],[-97.16302,42.800343],[-97.015142,42.762004],[-97.015142,42.351234],[-97.365666,42.351234],[-97.365666,42.438865],[-97.486159,42.438865],[-97.486159,42.849635]]]}}, -{"type":"Feature","id":"31029","properties":{"name":"Chase"},"geometry":{"type":"Polygon","coordinates":[[[-101.571957,40.697198],[-101.347402,40.697198],[-101.341925,40.35215],[-102.053927,40.346673],[-102.053927,40.439781],[-102.053927,40.697198],[-101.571957,40.697198]]]}}, -{"type":"Feature","id":"31031","properties":{"name":"Cherry"},"geometry":{"type":"Polygon","coordinates":[[[-102.081312,42.997512],[-102.081312,42.997512],[-101.226909,42.997512],[-100.197245,42.997512],[-100.197245,42.844158],[-100.16986,42.08834],[-100.268445,42.08834],[-100.843524,42.08834],[-101.424079,42.093817],[-102.004635,42.093817],[-102.081312,42.997512]]]}}, -{"type":"Feature","id":"31033","properties":{"name":"Cheyenne"},"geometry":{"type":"Polygon","coordinates":[[[-102.754976,41.436584],[-102.634483,41.436584],[-102.612575,41.222984],[-102.623529,41.003906],[-102.650914,41.003906],[-103.384824,41.003906],[-103.379347,41.392769],[-103.368393,41.436584],[-102.754976,41.436584]]]}}, -{"type":"Feature","id":"31035","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-97.825729,40.697198],[-97.825729,40.35215],[-98.011945,40.35215],[-98.274839,40.35215],[-98.280315,40.35215],[-98.280315,40.697198],[-97.825729,40.697198],[-97.825729,40.697198]]]}}, -{"type":"Feature","id":"31037","properties":{"name":"Colfax"},"geometry":{"type":"Polygon","coordinates":[[[-97.250651,41.743293],[-97.020619,41.743293],[-96.905603,41.743293],[-96.905603,41.453015],[-97.256128,41.376338],[-97.250651,41.743293],[-97.250651,41.743293]]]}}, -{"type":"Feature","id":"31039","properties":{"name":"Cuming"},"geometry":{"type":"Polygon","coordinates":[[[-96.89465,42.08834],[-96.823449,42.08834],[-96.555079,42.01714],[-96.555079,41.743293],[-96.905603,41.743293],[-97.020619,41.743293],[-97.020619,42.08834],[-96.89465,42.08834]]]}}, -{"type":"Feature","id":"31041","properties":{"name":"Custer"},"geometry":{"type":"Polygon","coordinates":[[[-99.222349,41.743293],[-99.211395,41.743293],[-99.205918,41.392769],[-99.205918,41.047722],[-99.424996,41.047722],[-99.994598,41.047722],[-100.224629,41.047722],[-100.252014,41.392769],[-100.252014,41.737816],[-99.687889,41.737816],[-99.222349,41.743293]]]}}, -{"type":"Feature","id":"31043","properties":{"name":"Dakota"},"geometry":{"type":"Polygon","coordinates":[[[-96.724864,42.395049],[-96.631756,42.526496],[-96.44554,42.488157],[-96.357909,42.274556],[-96.724864,42.280033],[-96.724864,42.395049]]]}}, -{"type":"Feature","id":"31045","properties":{"name":"Dawes"},"geometry":{"type":"Polygon","coordinates":[[[-103.324578,43.002989],[-103.001438,43.002989],[-102.793314,42.997512],[-102.771407,42.438865],[-103.44507,42.438865],[-103.505317,43.002989],[-103.324578,43.002989]]]}}, -{"type":"Feature","id":"31047","properties":{"name":"Dawson"},"geometry":{"type":"Polygon","coordinates":[[[-99.994598,41.047722],[-99.424996,41.047722],[-99.419519,40.669813],[-99.644074,40.686244],[-99.983644,40.697198],[-100.224629,40.702674],[-100.224629,41.047722],[-99.994598,41.047722]]]}}, -{"type":"Feature","id":"31049","properties":{"name":"Deuel"},"geometry":{"type":"Polygon","coordinates":[[[-102.119651,41.222984],[-102.053927,41.222984],[-102.053927,41.003906],[-102.053927,41.003906],[-102.623529,41.003906],[-102.612575,41.222984],[-102.119651,41.222984]]]}}, -{"type":"Feature","id":"31051","properties":{"name":"Dixon"},"geometry":{"type":"Polygon","coordinates":[[[-97.015142,42.762004],[-96.807019,42.701758],[-96.631756,42.526496],[-96.724864,42.395049],[-96.724864,42.280033],[-96.823449,42.263602],[-97.015142,42.351234],[-97.015142,42.762004]]]}}, -{"type":"Feature","id":"31053","properties":{"name":"Dodge"},"geometry":{"type":"Polygon","coordinates":[[[-96.905603,41.743293],[-96.555079,41.743293],[-96.44554,41.683047],[-96.330525,41.392769],[-96.461971,41.392769],[-96.472925,41.392769],[-96.905603,41.453015],[-96.905603,41.453015],[-96.905603,41.743293]]]}}, -{"type":"Feature","id":"31055","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-96.461971,41.392769],[-96.330525,41.392769],[-95.936185,41.392769],[-95.925231,41.190122],[-95.936185,41.190122],[-96.325048,41.190122],[-96.472925,41.392769],[-96.461971,41.392769]]]}}, -{"type":"Feature","id":"31057","properties":{"name":"Dundy"},"geometry":{"type":"Polygon","coordinates":[[[-101.325494,40.35215],[-101.325494,40.35215],[-101.325494,40.001626],[-101.413125,40.001626],[-101.90605,40.001626],[-102.053927,40.001626],[-102.053927,40.346673],[-101.341925,40.35215],[-101.325494,40.35215]]]}}, -{"type":"Feature","id":"31059","properties":{"name":"Fillmore"},"geometry":{"type":"Polygon","coordinates":[[[-97.798345,40.697198],[-97.365666,40.697198],[-97.365666,40.35215],[-97.50259,40.35215],[-97.820252,40.35215],[-97.825729,40.35215],[-97.825729,40.697198],[-97.798345,40.697198]]]}}, -{"type":"Feature","id":"31061","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-99.11281,40.35215],[-98.729425,40.35215],[-98.723948,40.001626],[-99.068995,40.001626],[-99.123764,40.001626],[-99.178534,40.001626],[-99.178534,40.35215],[-99.11281,40.35215]]]}}, -{"type":"Feature","id":"31063","properties":{"name":"Frontier"},"geometry":{"type":"Polygon","coordinates":[[[-100.449184,40.702674],[-100.224629,40.702674],[-99.983644,40.697198],[-100.093183,40.35215],[-100.197245,40.35215],[-100.383461,40.35215],[-100.755893,40.35215],[-100.7778,40.35215],[-100.7778,40.702674],[-100.449184,40.702674]]]}}, -{"type":"Feature","id":"31065","properties":{"name":"Furnas"},"geometry":{"type":"Polygon","coordinates":[[[-99.989121,40.35215],[-99.644074,40.35215],[-99.63312,40.35215],[-99.627643,40.001626],[-100.175337,40.001626],[-100.191768,40.001626],[-100.197245,40.35215],[-100.093183,40.35215],[-99.989121,40.35215]]]}}, -{"type":"Feature","id":"31067","properties":{"name":"Gage"},"geometry":{"type":"Polygon","coordinates":[[[-96.478402,40.521935],[-96.461971,40.521935],[-96.461971,40.264519],[-96.461971,40.001626],[-96.692003,40.001626],[-96.807019,40.001626],[-96.916557,40.001626],[-96.916557,40.35215],[-96.91108,40.521935],[-96.478402,40.521935]]]}}, -{"type":"Feature","id":"31069","properties":{"name":"Garden"},"geometry":{"type":"Polygon","coordinates":[[[-102.240143,42.006186],[-102.064881,42.011663],[-101.988204,41.743293],[-101.982727,41.392769],[-102.053927,41.222984],[-102.119651,41.222984],[-102.612575,41.222984],[-102.634483,41.436584],[-102.678299,42.006186],[-102.240143,42.006186]]]}}, -{"type":"Feature","id":"31071","properties":{"name":"Garfield"},"geometry":{"type":"Polygon","coordinates":[[[-98.762286,42.08834],[-98.756809,41.737816],[-99.074472,41.737816],[-99.211395,41.743293],[-99.222349,41.743293],[-99.222349,42.08834],[-98.762286,42.08834]]]}}, -{"type":"Feature","id":"31073","properties":{"name":"Gosper"},"geometry":{"type":"Polygon","coordinates":[[[-99.983644,40.697198],[-99.644074,40.686244],[-99.644074,40.35215],[-99.989121,40.35215],[-100.093183,40.35215],[-99.983644,40.697198]]]}}, -{"type":"Feature","id":"31075","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-102.004635,42.093817],[-101.424079,42.093817],[-101.424079,41.743293],[-101.988204,41.743293],[-102.064881,42.011663],[-102.004635,42.093817]]]}}, -{"type":"Feature","id":"31077","properties":{"name":"Greeley"},"geometry":{"type":"Polygon","coordinates":[[[-98.521301,41.743293],[-98.296746,41.743293],[-98.291269,41.4804],[-98.291269,41.392769],[-98.521301,41.392769],[-98.745855,41.392769],[-98.751332,41.392769],[-98.751332,41.737816],[-98.521301,41.743293]]]}}, -{"type":"Feature","id":"31079","properties":{"name":"Hall"},"geometry":{"type":"Polygon","coordinates":[[[-98.70204,41.047722],[-98.285792,41.047722],[-98.280315,40.87246],[-98.280315,40.697198],[-98.723948,40.697198],[-98.723948,41.047722],[-98.70204,41.047722]]]}}, -{"type":"Feature","id":"31081","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-97.825729,41.047722],[-97.825729,40.697198],[-98.280315,40.697198],[-98.280315,40.697198],[-98.280315,40.87246],[-97.825729,41.173691],[-97.825729,41.047722]]]}}, -{"type":"Feature","id":"31083","properties":{"name":"Harlan"},"geometry":{"type":"Polygon","coordinates":[[[-99.63312,40.35215],[-99.178534,40.35215],[-99.178534,40.001626],[-99.627643,40.001626],[-99.627643,40.001626],[-99.63312,40.35215]]]}}, -{"type":"Feature","id":"31085","properties":{"name":"Hayes"},"geometry":{"type":"Polygon","coordinates":[[[-100.7778,40.702674],[-100.7778,40.35215],[-101.111894,40.35215],[-101.325494,40.35215],[-101.325494,40.35215],[-101.341925,40.35215],[-101.347402,40.697198],[-101.248817,40.697198],[-100.7778,40.702674]]]}}, -{"type":"Feature","id":"31087","properties":{"name":"Hitchcock"},"geometry":{"type":"Polygon","coordinates":[[[-101.111894,40.35215],[-100.7778,40.35215],[-100.755893,40.35215],[-100.761369,40.001626],[-101.325494,40.001626],[-101.325494,40.35215],[-101.111894,40.35215]]]}}, -{"type":"Feature","id":"31089","properties":{"name":"Holt"},"geometry":{"type":"Polygon","coordinates":[[[-98.997795,42.887974],[-98.3077,42.762004],[-98.302223,42.438865],[-98.302223,42.08834],[-98.762286,42.08834],[-99.222349,42.08834],[-99.233303,42.08834],[-99.255211,42.80582],[-98.997795,42.887974]]]}}, -{"type":"Feature","id":"31091","properties":{"name":"Hooker"},"geometry":{"type":"Polygon","coordinates":[[[-101.424079,42.093817],[-100.843524,42.08834],[-100.843524,41.737816],[-101.407648,41.743293],[-101.424079,41.743293],[-101.424079,42.093817]]]}}, -{"type":"Feature","id":"31093","properties":{"name":"Howard"},"geometry":{"type":"Polygon","coordinates":[[[-98.521301,41.392769],[-98.291269,41.392769],[-98.285792,41.392769],[-98.285792,41.047722],[-98.70204,41.047722],[-98.723948,41.047722],[-98.745855,41.047722],[-98.745855,41.392769],[-98.521301,41.392769]]]}}, -{"type":"Feature","id":"31095","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-97.365666,40.35215],[-96.916557,40.35215],[-96.916557,40.001626],[-97.349236,40.001626],[-97.371143,40.001626],[-97.365666,40.35215]]]}}, -{"type":"Feature","id":"31097","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-96.067632,40.521935],[-96.067632,40.264519],[-96.325048,40.264519],[-96.461971,40.264519],[-96.461971,40.521935],[-96.067632,40.521935]]]}}, -{"type":"Feature","id":"31099","properties":{"name":"Kearney"},"geometry":{"type":"Polygon","coordinates":[[[-98.953979,40.653382],[-98.723948,40.691721],[-98.723948,40.35215],[-98.729425,40.35215],[-99.11281,40.35215],[-99.178534,40.35215],[-99.178534,40.658859],[-98.953979,40.653382]]]}}, -{"type":"Feature","id":"31101","properties":{"name":"Keith"},"geometry":{"type":"Polygon","coordinates":[[[-101.363833,41.392769],[-101.270725,41.392769],[-101.248817,41.003906],[-101.878665,41.003906],[-102.053927,41.003906],[-102.053927,41.222984],[-101.982727,41.392769],[-101.407648,41.392769],[-101.363833,41.392769]]]}}, -{"type":"Feature","id":"31103","properties":{"name":"Keya Paha"},"geometry":{"type":"Polygon","coordinates":[[[-100.126044,42.997512],[-99.534535,42.997512],[-99.255211,42.997512],[-99.255211,42.80582],[-99.676935,42.729142],[-100.175337,42.833204],[-100.197245,42.844158],[-100.197245,42.997512],[-100.126044,42.997512]]]}}, -{"type":"Feature","id":"31105","properties":{"name":"Kimball"},"geometry":{"type":"Polygon","coordinates":[[[-103.379347,41.392769],[-103.384824,41.003906],[-103.576517,41.003906],[-104.053011,41.003906],[-104.053011,41.392769],[-103.379347,41.392769]]]}}, -{"type":"Feature","id":"31107","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-98.3077,42.882497],[-98.154346,42.838681],[-97.634037,42.849635],[-97.486159,42.849635],[-97.486159,42.438865],[-97.836683,42.438865],[-98.302223,42.438865],[-98.3077,42.762004],[-98.3077,42.882497]]]}}, -{"type":"Feature","id":"31109","properties":{"name":"Lancaster"},"geometry":{"type":"Polygon","coordinates":[[[-96.91108,41.047722],[-96.461971,41.01486],[-96.461971,40.784829],[-96.461971,40.521935],[-96.478402,40.521935],[-96.91108,40.521935],[-96.91108,40.697198],[-96.91108,41.047722],[-96.91108,41.047722]]]}}, -{"type":"Feature","id":"31111","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-101.270725,41.392769],[-100.712077,41.392769],[-100.252014,41.392769],[-100.224629,41.047722],[-100.224629,40.702674],[-100.449184,40.702674],[-100.7778,40.702674],[-101.248817,40.697198],[-101.248817,41.003906],[-101.270725,41.392769]]]}}, -{"type":"Feature","id":"31113","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-100.712077,41.737816],[-100.262968,41.737816],[-100.252014,41.737816],[-100.252014,41.392769],[-100.712077,41.392769],[-100.712077,41.737816]]]}}, -{"type":"Feature","id":"31115","properties":{"name":"Loup"},"geometry":{"type":"Polygon","coordinates":[[[-99.222349,42.08834],[-99.222349,41.743293],[-99.687889,41.737816],[-99.687889,42.08834],[-99.660504,42.08834],[-99.233303,42.08834],[-99.222349,42.08834]]]}}, -{"type":"Feature","id":"31117","properties":{"name":"McPherson"},"geometry":{"type":"Polygon","coordinates":[[[-101.407648,41.743293],[-100.843524,41.737816],[-100.712077,41.737816],[-100.712077,41.392769],[-101.270725,41.392769],[-101.363833,41.392769],[-101.407648,41.392769],[-101.407648,41.743293]]]}}, -{"type":"Feature","id":"31119","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-97.425913,42.08834],[-97.365666,42.08834],[-97.365666,41.743293],[-97.425913,41.743293],[-97.831206,41.743293],[-97.831206,41.918555],[-97.836683,42.08834],[-97.425913,42.08834]]]}}, -{"type":"Feature","id":"31121","properties":{"name":"Merrick"},"geometry":{"type":"Polygon","coordinates":[[[-97.705237,41.392769],[-97.601175,41.332523],[-97.825729,41.173691],[-98.280315,40.87246],[-98.285792,41.047722],[-98.285792,41.392769],[-97.705237,41.392769]]]}}, -{"type":"Feature","id":"31123","properties":{"name":"Morrill"},"geometry":{"type":"Polygon","coordinates":[[[-102.700206,42.006186],[-102.678299,42.006186],[-102.634483,41.436584],[-102.754976,41.436584],[-103.368393,41.436584],[-103.368393,41.699478],[-103.362916,42.000709],[-102.700206,42.006186]]]}}, -{"type":"Feature","id":"31125","properties":{"name":"Nance"},"geometry":{"type":"Polygon","coordinates":[[[-97.716191,41.524216],[-97.705237,41.392769],[-98.285792,41.392769],[-98.291269,41.392769],[-98.291269,41.4804],[-97.831206,41.524216],[-97.716191,41.524216]]]}}, -{"type":"Feature","id":"31127","properties":{"name":"Nemaha"},"geometry":{"type":"Polygon","coordinates":[[[-96.023816,40.521935],[-95.71163,40.521935],[-95.552799,40.264519],[-95.552799,40.264519],[-95.673292,40.264519],[-96.012862,40.259042],[-96.067632,40.264519],[-96.067632,40.521935],[-96.023816,40.521935]]]}}, -{"type":"Feature","id":"31129","properties":{"name":"Nuckolls"},"geometry":{"type":"Polygon","coordinates":[[[-98.011945,40.35215],[-97.825729,40.35215],[-97.820252,40.35215],[-97.820252,40.001626],[-97.875022,40.001626],[-97.929791,40.001626],[-98.269362,40.001626],[-98.274839,40.001626],[-98.274839,40.35215],[-98.011945,40.35215]]]}}, -{"type":"Feature","id":"31131","properties":{"name":"Otoe"},"geometry":{"type":"Polygon","coordinates":[[[-95.892369,40.784829],[-95.832123,40.784829],[-95.7664,40.587659],[-95.71163,40.521935],[-96.023816,40.521935],[-96.067632,40.521935],[-96.461971,40.521935],[-96.461971,40.784829],[-95.892369,40.784829]]]}}, -{"type":"Feature","id":"31133","properties":{"name":"Pawnee"},"geometry":{"type":"Polygon","coordinates":[[[-96.325048,40.264519],[-96.067632,40.264519],[-96.012862,40.259042],[-96.012862,40.001626],[-96.237417,40.001626],[-96.237417,40.001626],[-96.461971,40.001626],[-96.461971,40.264519],[-96.325048,40.264519]]]}}, -{"type":"Feature","id":"31135","properties":{"name":"Perkins"},"geometry":{"type":"Polygon","coordinates":[[[-101.878665,41.003906],[-101.248817,41.003906],[-101.248817,40.697198],[-101.347402,40.697198],[-101.571957,40.697198],[-102.053927,40.697198],[-102.053927,40.751967],[-102.053927,41.003906],[-102.053927,41.003906],[-101.878665,41.003906]]]}}, -{"type":"Feature","id":"31137","properties":{"name":"Phelps"},"geometry":{"type":"Polygon","coordinates":[[[-99.644074,40.686244],[-99.419519,40.669813],[-99.178534,40.658859],[-99.178534,40.35215],[-99.63312,40.35215],[-99.644074,40.35215],[-99.644074,40.686244]]]}}, -{"type":"Feature","id":"31139","properties":{"name":"Pierce"},"geometry":{"type":"Polygon","coordinates":[[[-97.365666,42.438865],[-97.365666,42.351234],[-97.365666,42.08834],[-97.425913,42.08834],[-97.836683,42.08834],[-97.836683,42.438865],[-97.486159,42.438865],[-97.365666,42.438865]]]}}, -{"type":"Feature","id":"31141","properties":{"name":"Platte"},"geometry":{"type":"Polygon","coordinates":[[[-97.425913,41.743293],[-97.365666,41.743293],[-97.250651,41.743293],[-97.256128,41.376338],[-97.365666,41.392769],[-97.601175,41.332523],[-97.705237,41.392769],[-97.716191,41.524216],[-97.831206,41.524216],[-97.831206,41.743293],[-97.425913,41.743293]]]}}, -{"type":"Feature","id":"31143","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-97.365666,41.392769],[-97.365666,41.047722],[-97.825729,41.047722],[-97.825729,41.173691],[-97.601175,41.332523],[-97.365666,41.392769]]]}}, -{"type":"Feature","id":"31145","properties":{"name":"Red Willow"},"geometry":{"type":"Polygon","coordinates":[[[-100.383461,40.35215],[-100.197245,40.35215],[-100.191768,40.001626],[-100.739462,40.001626],[-100.761369,40.001626],[-100.755893,40.35215],[-100.383461,40.35215]]]}}, -{"type":"Feature","id":"31147","properties":{"name":"Richardson"},"geometry":{"type":"Polygon","coordinates":[[[-95.673292,40.264519],[-95.552799,40.264519],[-95.306337,40.001626],[-95.339199,40.001626],[-95.788308,40.001626],[-96.012862,40.001626],[-96.012862,40.259042],[-95.673292,40.264519]]]}}, -{"type":"Feature","id":"31149","properties":{"name":"Rock"},"geometry":{"type":"Polygon","coordinates":[[[-99.255211,42.80582],[-99.233303,42.08834],[-99.660504,42.08834],[-99.676935,42.729142],[-99.255211,42.80582]]]}}, -{"type":"Feature","id":"31151","properties":{"name":"Saline"},"geometry":{"type":"Polygon","coordinates":[[[-97.365666,40.697198],[-96.91108,40.697198],[-96.91108,40.521935],[-96.916557,40.35215],[-97.365666,40.35215],[-97.365666,40.697198]]]}}, -{"type":"Feature","id":"31153","properties":{"name":"Sarpy"},"geometry":{"type":"Polygon","coordinates":[[[-95.936185,41.190122],[-95.925231,41.190122],[-95.881416,41.157261],[-95.881416,41.053199],[-96.040247,41.064153],[-96.319571,41.047722],[-96.325048,41.190122],[-95.936185,41.190122]]]}}, -{"type":"Feature","id":"31155","properties":{"name":"Saunders"},"geometry":{"type":"Polygon","coordinates":[[[-96.905603,41.453015],[-96.472925,41.392769],[-96.325048,41.190122],[-96.319571,41.047722],[-96.461971,41.01486],[-96.91108,41.047722],[-96.905603,41.453015]]]}}, -{"type":"Feature","id":"31157","properties":{"name":"Scotts Bluff"},"geometry":{"type":"Polygon","coordinates":[[[-103.456024,42.006186],[-103.401255,42.006186],[-103.362916,42.000709],[-103.368393,41.699478],[-104.053011,41.699478],[-104.053011,42.000709],[-103.456024,42.006186]]]}}, -{"type":"Feature","id":"31159","properties":{"name":"Seward"},"geometry":{"type":"Polygon","coordinates":[[[-97.349236,41.047722],[-96.91108,41.047722],[-96.91108,40.697198],[-97.365666,40.697198],[-97.365666,41.047722],[-97.349236,41.047722]]]}}, -{"type":"Feature","id":"31161","properties":{"name":"Sheridan"},"geometry":{"type":"Polygon","coordinates":[[[-102.081312,42.997512],[-102.004635,42.093817],[-102.064881,42.011663],[-102.240143,42.006186],[-102.678299,42.006186],[-102.700206,42.006186],[-102.771407,42.438865],[-102.793314,42.997512],[-102.081312,42.997512]]]}}, -{"type":"Feature","id":"31163","properties":{"name":"Sherman"},"geometry":{"type":"Polygon","coordinates":[[[-98.822533,41.392769],[-98.751332,41.392769],[-98.745855,41.392769],[-98.745855,41.047722],[-99.052564,41.047722],[-99.205918,41.047722],[-99.205918,41.392769],[-98.822533,41.392769]]]}}, -{"type":"Feature","id":"31165","properties":{"name":"Sioux"},"geometry":{"type":"Polygon","coordinates":[[[-103.505317,43.002989],[-103.44507,42.438865],[-103.401255,42.006186],[-103.456024,42.006186],[-104.053011,42.000709],[-104.053011,42.614127],[-104.053011,43.002989],[-103.505317,43.002989]]]}}, -{"type":"Feature","id":"31167","properties":{"name":"Stanton"},"geometry":{"type":"Polygon","coordinates":[[[-97.36019,42.08834],[-97.020619,42.08834],[-97.020619,41.743293],[-97.250651,41.743293],[-97.250651,41.743293],[-97.365666,41.743293],[-97.365666,42.08834],[-97.36019,42.08834]]]}}, -{"type":"Feature","id":"31169","properties":{"name":"Thayer"},"geometry":{"type":"Polygon","coordinates":[[[-97.50259,40.35215],[-97.365666,40.35215],[-97.371143,40.001626],[-97.820252,40.001626],[-97.820252,40.35215],[-97.50259,40.35215]]]}}, -{"type":"Feature","id":"31171","properties":{"name":"Thomas"},"geometry":{"type":"Polygon","coordinates":[[[-100.843524,42.08834],[-100.268445,42.08834],[-100.262968,41.737816],[-100.712077,41.737816],[-100.843524,41.737816],[-100.843524,42.08834]]]}}, -{"type":"Feature","id":"31173","properties":{"name":"Thurston"},"geometry":{"type":"Polygon","coordinates":[[[-96.724864,42.280033],[-96.357909,42.274556],[-96.357909,42.21431],[-96.270278,42.044525],[-96.555079,42.01714],[-96.823449,42.08834],[-96.823449,42.263602],[-96.724864,42.280033]]]}}, -{"type":"Feature","id":"31175","properties":{"name":"Valley"},"geometry":{"type":"Polygon","coordinates":[[[-99.074472,41.737816],[-98.756809,41.737816],[-98.751332,41.737816],[-98.751332,41.392769],[-98.822533,41.392769],[-99.205918,41.392769],[-99.211395,41.743293],[-99.074472,41.737816]]]}}, -{"type":"Feature","id":"31177","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-96.407202,41.683047],[-96.122401,41.683047],[-95.996431,41.507785],[-95.936185,41.392769],[-96.330525,41.392769],[-96.44554,41.683047],[-96.407202,41.683047]]]}}, -{"type":"Feature","id":"31179","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-97.365666,42.351234],[-97.015142,42.351234],[-96.823449,42.263602],[-96.823449,42.08834],[-96.89465,42.08834],[-97.020619,42.08834],[-97.36019,42.08834],[-97.365666,42.08834],[-97.365666,42.351234]]]}}, -{"type":"Feature","id":"31181","properties":{"name":"Webster"},"geometry":{"type":"Polygon","coordinates":[[[-98.291269,40.35215],[-98.280315,40.35215],[-98.274839,40.35215],[-98.274839,40.001626],[-98.50487,40.001626],[-98.691086,40.001626],[-98.723948,40.001626],[-98.729425,40.35215],[-98.723948,40.35215],[-98.291269,40.35215]]]}}, -{"type":"Feature","id":"31183","properties":{"name":"Wheeler"},"geometry":{"type":"Polygon","coordinates":[[[-98.302223,42.08834],[-98.296746,41.913078],[-98.296746,41.743293],[-98.521301,41.743293],[-98.751332,41.737816],[-98.756809,41.737816],[-98.762286,42.08834],[-98.302223,42.08834]]]}}, -{"type":"Feature","id":"31185","properties":{"name":"York"},"geometry":{"type":"Polygon","coordinates":[[[-97.365666,41.047722],[-97.365666,40.697198],[-97.798345,40.697198],[-97.825729,40.697198],[-97.825729,40.697198],[-97.825729,41.047722],[-97.365666,41.047722]]]}}, -{"type":"Feature","id":"32001","properties":{"name":"Churchill"},"geometry":{"type":"Polygon","coordinates":[[[-117.948008,40.001626],[-117.542715,40.001626],[-117.493422,39.530609],[-117.772746,39.092454],[-117.865854,39.076023],[-118.753119,39.076023],[-119.191274,39.629194],[-119.224135,40.001626],[-117.948008,40.001626]]]}}, -{"type":"Feature","id":"32003","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-114.081288,36.841432],[-114.048427,36.841432],[-114.048427,36.195153],[-114.754952,36.085614],[-114.634459,35.00118],[-115.647693,35.80629],[-115.899633,36.00346],[-115.894156,36.841432],[-114.081288,36.841432]]]}}, -{"type":"Feature","id":"32005","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-119.760876,39.114362],[-119.552752,39.086977],[-119.328197,38.533806],[-119.585614,38.714545],[-119.903276,38.933623],[-120.001861,39.065069],[-120.001861,39.114362],[-119.760876,39.114362]]]}}, -{"type":"Feature","id":"32007","properties":{"name":"Elko"},"geometry":{"type":"Polygon","coordinates":[[[-115.039753,41.995232],[-114.283935,41.995232],[-114.04295,41.995232],[-114.04295,40.998429],[-114.048427,40.116642],[-115.833909,40.127596],[-116.157049,40.998429],[-116.58425,40.998429],[-117.016928,40.998429],[-117.016928,42.000709],[-115.039753,41.995232]]]}}, -{"type":"Feature","id":"32009","properties":{"name":"Esmeralda"},"geometry":{"type":"Polygon","coordinates":[[[-117.690592,38.47356],[-117.164806,38.002543],[-117.164806,36.972878],[-117.832993,37.465803],[-118.429979,37.898481],[-117.690592,38.47356]]]}}, -{"type":"Feature","id":"32011","properties":{"name":"Eureka"},"geometry":{"type":"Polygon","coordinates":[[[-116.58425,40.998429],[-116.157049,40.998429],[-115.833909,40.127596],[-115.90511,39.163654],[-116.233726,39.163654],[-116.600681,39.163654],[-116.58425,40.998429]]]}}, -{"type":"Feature","id":"32013","properties":{"name":"Humboldt"},"geometry":{"type":"Polygon","coordinates":[[[-117.027882,42.000709],[-117.016928,42.000709],[-117.016928,40.998429],[-117.301729,40.527412],[-118.013732,40.856029],[-119.311766,40.960091],[-119.32272,41.995232],[-118.194471,41.995232],[-117.027882,42.000709]]]}}, -{"type":"Feature","id":"32015","properties":{"name":"Lander"},"geometry":{"type":"Polygon","coordinates":[[[-117.016928,40.998429],[-116.58425,40.998429],[-116.600681,39.163654],[-117.772746,39.092454],[-117.493422,39.530609],[-117.542715,40.001626],[-117.301729,40.527412],[-117.016928,40.998429]]]}}, -{"type":"Feature","id":"32017","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-114.70566,38.676207],[-114.048427,38.676207],[-114.048427,38.572145],[-114.048427,38.15042],[-114.053904,37.602726],[-114.048427,37.000263],[-114.048427,36.841432],[-114.081288,36.841432],[-115.894156,36.841432],[-115.894156,38.051835],[-115.001414,38.051835],[-115.001414,38.676207],[-114.70566,38.676207]]]}}, -{"type":"Feature","id":"32019","properties":{"name":"Lyon"},"geometry":{"type":"Polygon","coordinates":[[[-119.196751,39.623717],[-119.191274,39.629194],[-118.753119,39.076023],[-118.764072,39.076023],[-118.906473,38.413313],[-119.158412,38.413313],[-119.328197,38.533806],[-119.552752,39.086977],[-119.580137,39.196516],[-119.711583,39.251285],[-119.284382,39.623717],[-119.196751,39.623717]]]}}, -{"type":"Feature","id":"32021","properties":{"name":"Mineral"},"geometry":{"type":"Polygon","coordinates":[[[-118.764072,39.076023],[-118.753119,39.076023],[-117.865854,39.076023],[-118.194471,38.917192],[-117.690592,38.47356],[-118.429979,37.898481],[-119.158412,38.413313],[-118.906473,38.413313],[-118.764072,39.076023]]]}}, -{"type":"Feature","id":"32023","properties":{"name":"Nye"},"geometry":{"type":"Polygon","coordinates":[[[-116.233726,39.163654],[-115.90511,39.163654],[-115.001414,38.676207],[-115.001414,38.051835],[-115.894156,38.051835],[-115.894156,36.841432],[-115.899633,36.00346],[-117.164806,36.972878],[-117.164806,38.002543],[-117.690592,38.47356],[-118.194471,38.917192],[-117.865854,39.076023],[-117.772746,39.092454],[-116.600681,39.163654],[-116.233726,39.163654]]]}}, -{"type":"Feature","id":"32027","properties":{"name":"Pershing"},"geometry":{"type":"Polygon","coordinates":[[[-118.013732,40.856029],[-117.301729,40.527412],[-117.542715,40.001626],[-117.948008,40.001626],[-119.224135,40.001626],[-119.311766,40.960091],[-118.013732,40.856029]]]}}, -{"type":"Feature","id":"32029","properties":{"name":"Storey"},"geometry":{"type":"Polygon","coordinates":[[[-119.689675,39.519655],[-119.284382,39.623717],[-119.711583,39.251285],[-119.689675,39.519655]]]}}, -{"type":"Feature","id":"32031","properties":{"name":"Washoe"},"geometry":{"type":"Polygon","coordinates":[[[-119.361059,41.995232],[-119.32272,41.995232],[-119.311766,40.960091],[-119.224135,40.001626],[-119.191274,39.629194],[-119.196751,39.623717],[-119.284382,39.623717],[-119.689675,39.519655],[-119.711583,39.251285],[-120.001861,39.163654],[-120.007338,39.317009],[-120.001861,39.442978],[-120.001861,39.722302],[-120.001861,41.184645],[-120.001861,41.995232],[-119.361059,41.995232]]]}}, -{"type":"Feature","id":"32033","properties":{"name":"White Pine"},"geometry":{"type":"Polygon","coordinates":[[[-114.048427,40.116642],[-114.048427,39.908518],[-114.048427,39.541563],[-114.048427,38.676207],[-114.70566,38.676207],[-115.001414,38.676207],[-115.90511,39.163654],[-115.833909,40.127596],[-114.048427,40.116642]]]}}, -{"type":"Feature","id":"32510","properties":{"name":"Carson City"},"geometry":{"type":"Polygon","coordinates":[[[-119.580137,39.196516],[-119.552752,39.086977],[-119.760876,39.114362],[-120.001861,39.114362],[-120.001861,39.163654],[-119.711583,39.251285],[-119.580137,39.196516]]]}}, -{"type":"Feature","id":"33001","properties":{"name":"Belknap"},"geometry":{"type":"Polygon","coordinates":[[[-71.530939,43.764284],[-71.163984,43.53973],[-71.235184,43.282313],[-71.728109,43.561637],[-71.530939,43.764284]]]}}, -{"type":"Feature","id":"33003","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-71.010629,44.284593],[-70.988722,43.791669],[-70.961337,43.53973],[-71.109214,43.506868],[-71.163984,43.53973],[-71.530939,43.764284],[-71.415923,44.213393],[-71.010629,44.284593]]]}}, -{"type":"Feature","id":"33005","properties":{"name":"Cheshire"},"geometry":{"type":"Polygon","coordinates":[[[-72.199125,43.178252],[-72.040294,43.128959],[-71.930755,42.712712],[-72.28128,42.723665],[-72.456542,42.729142],[-72.451065,43.161821],[-72.199125,43.178252]]]}}, -{"type":"Feature","id":"33007","properties":{"name":"Coos"},"geometry":{"type":"Polygon","coordinates":[[[-71.08183,45.303304],[-71.010629,44.284593],[-71.415923,44.213393],[-71.766447,44.405086],[-71.503554,45.013027],[-71.08183,45.303304]]]}}, -{"type":"Feature","id":"33009","properties":{"name":"Grafton"},"geometry":{"type":"Polygon","coordinates":[[[-71.837647,44.350317],[-71.766447,44.405086],[-71.415923,44.213393],[-71.530939,43.764284],[-71.728109,43.561637],[-71.81574,43.545207],[-71.936232,43.528776],[-72.330572,43.599976],[-72.204602,43.769761],[-72.040294,44.153147],[-71.837647,44.350317]]]}}, -{"type":"Feature","id":"33011","properties":{"name":"Hillsborough"},"geometry":{"type":"Polygon","coordinates":[[[-71.914325,43.205636],[-71.394015,43.008466],[-71.246138,42.740096],[-71.257092,42.734619],[-71.897894,42.712712],[-71.930755,42.712712],[-72.040294,43.128959],[-72.007433,43.189205],[-71.914325,43.205636]]]}}, -{"type":"Feature","id":"33013","properties":{"name":"Merrimack"},"geometry":{"type":"Polygon","coordinates":[[[-71.81574,43.545207],[-71.728109,43.561637],[-71.235184,43.282313],[-71.246138,43.276836],[-71.394015,43.008466],[-71.914325,43.205636],[-72.007433,43.189205],[-71.936232,43.528776],[-71.81574,43.545207]]]}}, -{"type":"Feature","id":"33015","properties":{"name":"Rockingham"},"geometry":{"type":"Polygon","coordinates":[[[-71.246138,43.276836],[-70.818936,43.123482],[-70.703921,43.057759],[-70.818936,42.871543],[-70.917521,42.887974],[-71.246138,42.740096],[-71.394015,43.008466],[-71.246138,43.276836]]]}}, -{"type":"Feature","id":"33017","properties":{"name":"Strafford"},"geometry":{"type":"Polygon","coordinates":[[[-71.109214,43.506868],[-70.961337,43.53973],[-70.818936,43.123482],[-71.246138,43.276836],[-71.235184,43.282313],[-71.163984,43.53973],[-71.109214,43.506868]]]}}, -{"type":"Feature","id":"33019","properties":{"name":"Sullivan"},"geometry":{"type":"Polygon","coordinates":[[[-72.330572,43.599976],[-71.936232,43.528776],[-72.007433,43.189205],[-72.040294,43.128959],[-72.199125,43.178252],[-72.451065,43.161821],[-72.434634,43.233021],[-72.330572,43.599976]]]}}, -{"type":"Feature","id":"34001","properties":{"name":"Atlantic"},"geometry":{"type":"Polygon","coordinates":[[[-74.734949,39.727779],[-74.417286,39.557994],[-74.313224,39.497748],[-74.548733,39.295101],[-74.860918,39.322485],[-74.986888,39.514178],[-74.877349,39.607286],[-74.734949,39.727779]]]}}, -{"type":"Feature","id":"34003","properties":{"name":"Bergen"},"geometry":{"type":"Polygon","coordinates":[[[-74.21464,41.135353],[-73.8915,40.998429],[-73.918885,40.916275],[-73.918885,40.910798],[-73.935316,40.883413],[-73.984608,40.795782],[-74.011993,40.823167],[-74.148916,40.784829],[-74.132485,40.81769],[-74.21464,41.135353]]]}}, -{"type":"Feature","id":"34005","properties":{"name":"Burlington"},"geometry":{"type":"Polygon","coordinates":[[[-74.702087,40.182365],[-74.587071,40.13855],[-74.55421,40.078303],[-74.417286,39.557994],[-74.734949,39.727779],[-75.030704,39.990672],[-75.058088,39.990672],[-74.975934,40.050919],[-74.723995,40.149503],[-74.702087,40.182365]]]}}, -{"type":"Feature","id":"34007","properties":{"name":"Camden"},"geometry":{"type":"Polygon","coordinates":[[[-75.030704,39.990672],[-74.734949,39.727779],[-74.877349,39.607286],[-75.140242,39.88661],[-75.058088,39.990672],[-75.030704,39.990672]]]}}, -{"type":"Feature","id":"34009","properties":{"name":"Cape May"},"geometry":{"type":"Polygon","coordinates":[[[-74.860918,39.322485],[-74.548733,39.295101],[-74.915688,39.180085],[-74.860918,39.322485]]]}}, -{"type":"Feature","id":"34011","properties":{"name":"Cumberland"},"geometry":{"type":"Polygon","coordinates":[[[-75.058088,39.568948],[-74.986888,39.514178],[-74.860918,39.322485],[-74.915688,39.180085],[-75.408613,39.382732],[-75.063565,39.568948],[-75.058088,39.568948]]]}}, -{"type":"Feature","id":"34013","properties":{"name":"Essex"},"geometry":{"type":"Polygon","coordinates":[[[-74.28584,40.894367],[-74.269409,40.899844],[-74.132485,40.81769],[-74.148916,40.784829],[-74.137962,40.67529],[-74.362517,40.735536],[-74.373471,40.741013],[-74.28584,40.894367]]]}}, -{"type":"Feature","id":"34015","properties":{"name":"Gloucester"},"geometry":{"type":"Polygon","coordinates":[[[-75.211443,39.864703],[-75.140242,39.88661],[-74.877349,39.607286],[-74.986888,39.514178],[-75.058088,39.568948],[-75.063565,39.568948],[-75.446951,39.771595],[-75.414089,39.804456],[-75.211443,39.864703]]]}}, -{"type":"Feature","id":"34017","properties":{"name":"Hudson"},"geometry":{"type":"Polygon","coordinates":[[[-74.011993,40.823167],[-73.984608,40.795782],[-74.022947,40.708151],[-74.15987,40.642428],[-74.137962,40.67529],[-74.148916,40.784829],[-74.011993,40.823167]]]}}, -{"type":"Feature","id":"34019","properties":{"name":"Hunterdon"},"geometry":{"type":"Polygon","coordinates":[[[-74.888303,40.790306],[-74.723995,40.719105],[-74.745903,40.423351],[-74.800672,40.417874],[-74.943073,40.341196],[-75.189535,40.593136],[-74.888303,40.790306]]]}}, -{"type":"Feature","id":"34021","properties":{"name":"Mercer"},"geometry":{"type":"Polygon","coordinates":[[[-74.800672,40.417874],[-74.745903,40.423351],[-74.619933,40.374058],[-74.48301,40.253565],[-74.587071,40.13855],[-74.702087,40.182365],[-74.723995,40.149503],[-74.943073,40.341196],[-74.800672,40.417874]]]}}, -{"type":"Feature","id":"34023","properties":{"name":"Middlesex"},"geometry":{"type":"Polygon","coordinates":[[[-74.291317,40.593136],[-74.209163,40.593136],[-74.225593,40.450735],[-74.48301,40.253565],[-74.619933,40.374058],[-74.461102,40.598613],[-74.291317,40.593136]]]}}, -{"type":"Feature","id":"34025","properties":{"name":"Monmouth"},"geometry":{"type":"Polygon","coordinates":[[[-74.0339,40.100211],[-74.406332,40.171411],[-74.55421,40.078303],[-74.587071,40.13855],[-74.48301,40.253565],[-74.225593,40.450735],[-74.0339,40.100211]]]}}, -{"type":"Feature","id":"34027","properties":{"name":"Morris"},"geometry":{"type":"Polygon","coordinates":[[[-74.504917,41.08606],[-74.269409,40.899844],[-74.28584,40.894367],[-74.373471,40.741013],[-74.461102,40.67529],[-74.718518,40.719105],[-74.723995,40.719105],[-74.888303,40.790306],[-74.76781,40.910798],[-74.504917,41.08606]]]}}, -{"type":"Feature","id":"34029","properties":{"name":"Ocean"},"geometry":{"type":"Polygon","coordinates":[[[-74.406332,40.171411],[-74.0339,40.100211],[-74.313224,39.497748],[-74.417286,39.557994],[-74.55421,40.078303],[-74.406332,40.171411]]]}}, -{"type":"Feature","id":"34031","properties":{"name":"Passaic"},"geometry":{"type":"Polygon","coordinates":[[[-74.367994,41.201076],[-74.236547,41.14083],[-74.21464,41.135353],[-74.132485,40.81769],[-74.269409,40.899844],[-74.504917,41.08606],[-74.367994,41.201076]]]}}, -{"type":"Feature","id":"34033","properties":{"name":"Salem"},"geometry":{"type":"Polygon","coordinates":[[[-75.446951,39.771595],[-75.063565,39.568948],[-75.408613,39.382732],[-75.55649,39.607286],[-75.561967,39.629194],[-75.507197,39.683964],[-75.446951,39.771595]]]}}, -{"type":"Feature","id":"34035","properties":{"name":"Somerset"},"geometry":{"type":"Polygon","coordinates":[[[-74.718518,40.719105],[-74.461102,40.67529],[-74.461102,40.598613],[-74.619933,40.374058],[-74.745903,40.423351],[-74.723995,40.719105],[-74.718518,40.719105]]]}}, -{"type":"Feature","id":"34037","properties":{"name":"Sussex"},"geometry":{"type":"Polygon","coordinates":[[[-74.367994,41.201076],[-74.504917,41.08606],[-74.76781,40.910798],[-74.96498,41.091537],[-74.96498,41.097014],[-74.992365,41.091537],[-74.69661,41.359907],[-74.367994,41.201076]]]}}, -{"type":"Feature","id":"34039","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-74.362517,40.735536],[-74.137962,40.67529],[-74.15987,40.642428],[-74.209163,40.593136],[-74.291317,40.593136],[-74.461102,40.598613],[-74.461102,40.67529],[-74.373471,40.741013],[-74.362517,40.735536]]]}}, -{"type":"Feature","id":"34041","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-74.96498,41.091537],[-74.76781,40.910798],[-74.888303,40.790306],[-75.189535,40.593136],[-75.195012,40.609566],[-75.118335,40.965568],[-74.96498,41.097014],[-74.96498,41.091537]]]}}, -{"type":"Feature","id":"35001","properties":{"name":"Bernalillo"},"geometry":{"type":"Polygon","coordinates":[[[-107.196774,35.220257],[-106.243787,35.21478],[-106.243787,35.039518],[-106.413572,34.869733],[-107.065328,34.957364],[-107.196774,35.220257]]]}}, -{"type":"Feature","id":"35003","properties":{"name":"Catron"},"geometry":{"type":"Polygon","coordinates":[[[-108.987734,34.579455],[-107.722561,34.579455],[-107.711607,33.47859],[-108.001885,33.199266],[-108.182624,33.199266],[-109.04798,33.21022],[-109.04798,33.779822],[-109.04798,34.579455],[-108.987734,34.579455]]]}}, -{"type":"Feature","id":"35005","properties":{"name":"Chaves"},"geometry":{"type":"Polygon","coordinates":[[[-103.877749,34.081054],[-103.510794,33.571698],[-103.812025,32.963758],[-104.102303,32.963758],[-104.84169,32.963758],[-104.852644,32.520126],[-105.356522,32.520126],[-105.318184,33.133543],[-104.907413,33.13902],[-104.890983,34.08653],[-103.943472,34.081054],[-103.877749,34.081054]]]}}, -{"type":"Feature","id":"35006","properties":{"name":"Cibola"},"geometry":{"type":"Polygon","coordinates":[[[-107.985454,35.307888],[-107.31179,35.307888],[-107.196774,35.220257],[-107.065328,34.957364],[-107.196774,34.957364],[-107.202251,34.579455],[-107.536345,34.579455],[-107.722561,34.579455],[-108.987734,34.579455],[-109.04798,34.579455],[-109.04798,34.957364],[-108.467425,34.957364],[-108.467425,35.307888],[-107.985454,35.307888]]]}}, -{"type":"Feature","id":"35007","properties":{"name":"Colfax"},"geometry":{"type":"Polygon","coordinates":[[[-104.009195,36.994786],[-104.009195,36.21706],[-104.436396,36.21706],[-105.340092,36.260876],[-105.219599,36.994786],[-105.153876,36.994786],[-104.009195,36.994786]]]}}, -{"type":"Feature","id":"35009","properties":{"name":"Curry"},"geometry":{"type":"Polygon","coordinates":[[[-103.264331,34.951887],[-103.045254,34.951887],[-103.045254,34.74924],[-103.045254,34.311085],[-103.045254,34.300131],[-103.740825,34.305608],[-103.740825,34.60684],[-103.264331,34.951887]]]}}, -{"type":"Feature","id":"35011","properties":{"name":"De Baca"},"geometry":{"type":"Polygon","coordinates":[[[-104.129688,34.776625],[-103.948949,34.60684],[-103.943472,34.081054],[-104.890983,34.08653],[-104.890983,34.349424],[-104.890983,34.60684],[-104.129688,34.776625]]]}}, -{"type":"Feature","id":"35013","properties":{"name":"Dona Ana"},"geometry":{"type":"Polygon","coordinates":[[[-106.342372,33.051389],[-106.375233,31.999816],[-106.528588,31.786216],[-107.295359,31.786216],[-107.300836,32.607757],[-107.300836,32.777542],[-106.342372,33.051389]]]}}, -{"type":"Feature","id":"35015","properties":{"name":"Eddy"},"geometry":{"type":"Polygon","coordinates":[[[-104.102303,32.963758],[-103.812025,32.963758],[-103.724394,31.999816],[-103.98181,31.999816],[-104.025626,31.999816],[-104.847167,31.999816],[-104.852644,32.520126],[-104.84169,32.963758],[-104.102303,32.963758]]]}}, -{"type":"Feature","id":"35017","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-108.182624,33.199266],[-108.001885,33.199266],[-107.607545,32.607757],[-108.231916,32.514649],[-108.215485,31.862893],[-108.522194,31.862893],[-108.538625,32.514649],[-109.04798,32.777542],[-109.04798,33.21022],[-108.182624,33.199266]]]}}, -{"type":"Feature","id":"35019","properties":{"name":"Guadalupe"},"geometry":{"type":"Polygon","coordinates":[[[-104.124211,35.14358],[-104.129688,34.776625],[-104.890983,34.60684],[-104.890983,34.349424],[-105.312707,34.349424],[-105.290799,35.039518],[-105.290799,35.21478],[-104.124211,35.14358]]]}}, -{"type":"Feature","id":"35021","properties":{"name":"Harding"},"geometry":{"type":"Polygon","coordinates":[[[-104.436396,36.21706],[-104.009195,36.21706],[-103.362916,36.085614],[-103.37387,35.740566],[-103.636763,35.390042],[-103.976333,35.800813],[-104.365196,35.778905],[-104.436396,36.21706]]]}}, -{"type":"Feature","id":"35023","properties":{"name":"Hidalgo"},"geometry":{"type":"Polygon","coordinates":[[[-109.04798,32.777542],[-108.538625,32.514649],[-108.522194,31.862893],[-108.215485,31.862893],[-108.210008,31.786216],[-108.210008,31.331629],[-109.04798,31.331629],[-109.04798,32.427018],[-109.04798,32.777542]]]}}, -{"type":"Feature","id":"35025","properties":{"name":"Lea"},"geometry":{"type":"Polygon","coordinates":[[[-103.050731,33.571698],[-103.056207,33.390959],[-103.067161,32.958281],[-103.067161,32.520126],[-103.061684,32.087447],[-103.324578,31.999816],[-103.71344,31.999816],[-103.724394,31.999816],[-103.812025,32.963758],[-103.510794,33.571698],[-103.050731,33.571698]]]}}, -{"type":"Feature","id":"35027","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-104.890983,34.349424],[-104.890983,34.08653],[-104.907413,33.13902],[-105.318184,33.133543],[-105.728954,33.390959],[-106.347849,33.390959],[-106.375233,33.47859],[-106.052094,33.648375],[-105.926124,34.261793],[-105.312707,34.349424],[-104.890983,34.349424]]]}}, -{"type":"Feature","id":"35028","properties":{"name":"Los Alamos"},"geometry":{"type":"Polygon","coordinates":[[[-106.249264,35.965121],[-106.243787,35.932259],[-106.249264,35.855582],[-106.249264,35.839151],[-106.249264,35.756997],[-106.249264,35.965121]]]}}, -{"type":"Feature","id":"35029","properties":{"name":"Luna"},"geometry":{"type":"Polygon","coordinates":[[[-107.607545,32.607757],[-107.300836,32.607757],[-107.295359,31.786216],[-108.210008,31.786216],[-108.215485,31.862893],[-108.231916,32.514649],[-107.607545,32.607757]]]}}, -{"type":"Feature","id":"35031","properties":{"name":"McKinley"},"geometry":{"type":"Polygon","coordinates":[[[-108.883672,36.00346],[-107.623976,35.997983],[-107.306313,35.997983],[-107.31179,35.307888],[-107.985454,35.307888],[-108.467425,35.307888],[-108.467425,34.957364],[-109.04798,34.957364],[-109.04798,36.00346],[-108.883672,36.00346]]]}}, -{"type":"Feature","id":"35033","properties":{"name":"Mora"},"geometry":{"type":"Polygon","coordinates":[[[-105.340092,36.260876],[-104.436396,36.21706],[-104.365196,35.778905],[-105.718001,35.872013],[-105.718001,35.976075],[-105.531785,36.014414],[-105.340092,36.260876]]]}}, -{"type":"Feature","id":"35035","properties":{"name":"Otero"},"geometry":{"type":"Polygon","coordinates":[[[-105.728954,33.390959],[-105.318184,33.133543],[-105.356522,32.520126],[-104.852644,32.520126],[-104.847167,31.999816],[-104.918367,31.999816],[-105.997324,31.999816],[-106.375233,31.999816],[-106.342372,33.051389],[-106.347849,33.390959],[-105.728954,33.390959]]]}}, -{"type":"Feature","id":"35037","properties":{"name":"Quay"},"geometry":{"type":"Polygon","coordinates":[[[-103.37387,35.740566],[-103.039777,35.740566],[-103.039777,35.620074],[-103.039777,35.181919],[-103.045254,34.951887],[-103.264331,34.951887],[-103.740825,34.60684],[-103.948949,34.60684],[-104.129688,34.776625],[-104.124211,35.14358],[-103.636763,35.390042],[-103.37387,35.740566]]]}}, -{"type":"Feature","id":"35039","properties":{"name":"Rio Arriba"},"geometry":{"type":"Polygon","coordinates":[[[-107.421329,37.000263],[-106.473818,36.994786],[-106.008278,36.994786],[-105.958986,36.353984],[-105.531785,36.014414],[-105.718001,35.976075],[-106.068525,35.997983],[-106.243787,35.932259],[-106.249264,35.965121],[-106.884589,36.21706],[-107.623976,36.222537],[-107.421329,37.000263]]]}}, -{"type":"Feature","id":"35041","properties":{"name":"Roosevelt"},"geometry":{"type":"Polygon","coordinates":[[[-103.740825,34.60684],[-103.740825,34.305608],[-103.045254,34.300131],[-103.045254,33.823637],[-103.050731,33.571698],[-103.510794,33.571698],[-103.877749,34.081054],[-103.943472,34.081054],[-103.948949,34.60684],[-103.740825,34.60684]]]}}, -{"type":"Feature","id":"35043","properties":{"name":"Sandoval"},"geometry":{"type":"Polygon","coordinates":[[[-107.623976,36.222537],[-106.884589,36.21706],[-106.249264,35.965121],[-106.249264,35.756997],[-106.243787,35.21478],[-107.196774,35.220257],[-107.31179,35.307888],[-107.306313,35.997983],[-107.623976,35.997983],[-107.623976,36.222537]]]}}, -{"type":"Feature","id":"35045","properties":{"name":"San Juan"},"geometry":{"type":"Polygon","coordinates":[[[-107.421329,37.000263],[-107.623976,36.222537],[-107.623976,35.997983],[-108.883672,36.00346],[-109.04798,36.00346],[-109.042503,37.000263],[-108.379794,37.000263],[-107.481575,37.000263],[-107.421329,37.000263]]]}}, -{"type":"Feature","id":"35047","properties":{"name":"San Miguel"},"geometry":{"type":"Polygon","coordinates":[[[-104.365196,35.778905],[-103.976333,35.800813],[-103.636763,35.390042],[-104.124211,35.14358],[-105.290799,35.21478],[-105.290799,35.039518],[-105.712524,35.039518],[-105.718001,35.872013],[-104.365196,35.778905]]]}}, -{"type":"Feature","id":"35049","properties":{"name":"Santa Fe"},"geometry":{"type":"Polygon","coordinates":[[[-106.068525,35.997983],[-105.718001,35.976075],[-105.718001,35.872013],[-105.712524,35.039518],[-106.243787,35.039518],[-106.243787,35.21478],[-106.249264,35.756997],[-106.249264,35.839151],[-106.249264,35.855582],[-106.243787,35.932259],[-106.068525,35.997983]]]}}, -{"type":"Feature","id":"35051","properties":{"name":"Sierra"},"geometry":{"type":"Polygon","coordinates":[[[-106.375233,33.47859],[-106.347849,33.390959],[-106.342372,33.051389],[-107.300836,32.777542],[-107.300836,32.607757],[-107.607545,32.607757],[-108.001885,33.199266],[-107.711607,33.47859],[-106.375233,33.47859]]]}}, -{"type":"Feature","id":"35053","properties":{"name":"Socorro"},"geometry":{"type":"Polygon","coordinates":[[[-107.536345,34.579455],[-107.202251,34.579455],[-106.419049,34.442532],[-105.926124,34.261793],[-106.052094,33.648375],[-106.375233,33.47859],[-107.711607,33.47859],[-107.722561,34.579455],[-107.536345,34.579455]]]}}, -{"type":"Feature","id":"35055","properties":{"name":"Taos"},"geometry":{"type":"Polygon","coordinates":[[[-105.219599,36.994786],[-105.340092,36.260876],[-105.531785,36.014414],[-105.958986,36.353984],[-106.008278,36.994786],[-105.718001,36.994786],[-105.219599,36.994786]]]}}, -{"type":"Feature","id":"35057","properties":{"name":"Torrance"},"geometry":{"type":"Polygon","coordinates":[[[-105.290799,35.039518],[-105.312707,34.349424],[-105.926124,34.261793],[-106.419049,34.442532],[-106.413572,34.869733],[-106.243787,35.039518],[-105.712524,35.039518],[-105.290799,35.039518]]]}}, -{"type":"Feature","id":"35059","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-103.001438,37.000263],[-103.001438,36.501861],[-103.039777,36.052752],[-103.039777,35.740566],[-103.37387,35.740566],[-103.362916,36.085614],[-104.009195,36.21706],[-104.009195,36.994786],[-103.083592,37.000263],[-103.001438,37.000263]]]}}, -{"type":"Feature","id":"35061","properties":{"name":"Valencia"},"geometry":{"type":"Polygon","coordinates":[[[-107.196774,34.957364],[-107.065328,34.957364],[-106.413572,34.869733],[-106.419049,34.442532],[-107.202251,34.579455],[-107.196774,34.957364]]]}}, -{"type":"Feature","id":"36001","properties":{"name":"Albany"},"geometry":{"type":"Polygon","coordinates":[[[-73.809346,42.778435],[-73.677899,42.783912],[-73.781961,42.466249],[-74.252978,42.406003],[-74.181778,42.729142],[-73.809346,42.778435]]]}}, -{"type":"Feature","id":"36003","properties":{"name":"Allegany"},"geometry":{"type":"Polygon","coordinates":[[[-78.22376,42.521019],[-78.037544,42.521019],[-77.725358,42.471726],[-77.747266,42.000709],[-78.207329,42.000709],[-78.305914,42.000709],[-78.311391,42.521019],[-78.22376,42.521019]]]}}, -{"type":"Feature","id":"36005","properties":{"name":"Bronx"},"geometry":{"type":"Polygon","coordinates":[[[-73.918885,40.910798],[-73.918885,40.916275],[-73.781961,40.883413],[-73.787438,40.801259],[-73.814823,40.806736],[-73.913408,40.795782],[-73.924362,40.877937],[-73.935316,40.883413],[-73.918885,40.910798]]]}}, -{"type":"Feature","id":"36007","properties":{"name":"Broome"},"geometry":{"type":"Polygon","coordinates":[[[-75.863199,42.416957],[-75.419566,42.192402],[-75.35932,42.000709],[-75.479813,42.000709],[-75.48529,42.000709],[-75.890583,42.000709],[-76.104184,42.000709],[-76.131569,42.41148],[-75.863199,42.416957]]]}}, -{"type":"Feature","id":"36009","properties":{"name":"Cattaraugus"},"geometry":{"type":"Polygon","coordinates":[[[-79.001485,42.531973],[-78.464745,42.537449],[-78.311391,42.521019],[-78.305914,42.000709],[-78.919331,42.000709],[-79.061732,42.000709],[-79.061732,42.537449],[-79.001485,42.531973]]]}}, -{"type":"Feature","id":"36011","properties":{"name":"Cayuga"},"geometry":{"type":"Polygon","coordinates":[[[-76.619016,43.419237],[-76.476616,43.227544],[-76.273969,42.772958],[-76.263015,42.625081],[-76.460185,42.625081],[-76.668309,42.625081],[-76.712124,43.024897],[-76.723078,43.34256],[-76.619016,43.419237]]]}}, -{"type":"Feature","id":"36013","properties":{"name":"Chautauqua"},"geometry":{"type":"Polygon","coordinates":[[[-79.138409,42.570311],[-79.061732,42.537449],[-79.061732,42.000709],[-79.609426,42.000709],[-79.76278,42.252649],[-79.76278,42.269079],[-79.138409,42.570311],[-79.138409,42.570311]]]}}, -{"type":"Feature","id":"36015","properties":{"name":"Chemung"},"geometry":{"type":"Polygon","coordinates":[[[-76.766894,42.296464],[-76.619016,42.28551],[-76.536862,42.280033],[-76.55877,42.000709],[-76.920248,42.000709],[-76.925725,42.000709],[-76.964064,42.000709],[-76.964064,42.280033],[-76.766894,42.296464]]]}}, -{"type":"Feature","id":"36017","properties":{"name":"Chenango"},"geometry":{"type":"Polygon","coordinates":[[[-75.310028,42.745573],[-75.293597,42.745573],[-75.414089,42.312895],[-75.419566,42.192402],[-75.863199,42.416957],[-75.890583,42.723665],[-75.310028,42.745573]]]}}, -{"type":"Feature","id":"36019","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-73.343806,45.013027],[-73.360237,44.563917],[-73.338329,44.547487],[-73.907931,44.426994],[-74.028424,44.996596],[-73.343806,45.013027]]]}}, -{"type":"Feature","id":"36021","properties":{"name":"Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-73.398575,42.504588],[-73.35476,42.510065],[-73.49716,42.050002],[-73.929839,42.077386],[-73.913408,42.126679],[-73.781961,42.466249],[-73.398575,42.504588]]]}}, -{"type":"Feature","id":"36023","properties":{"name":"Cortland"},"geometry":{"type":"Polygon","coordinates":[[[-75.917968,42.789389],[-75.89606,42.789389],[-75.890583,42.723665],[-75.863199,42.416957],[-76.131569,42.41148],[-76.252061,42.406003],[-76.263015,42.625081],[-76.273969,42.772958],[-75.917968,42.789389]]]}}, -{"type":"Feature","id":"36025","properties":{"name":"Delaware"},"geometry":{"type":"Polygon","coordinates":[[[-74.844488,42.510065],[-74.713041,42.515542],[-74.444671,42.35671],[-74.450148,42.170494],[-74.778764,42.01714],[-74.789718,42.011663],[-75.145719,41.852832],[-75.35932,42.000709],[-75.419566,42.192402],[-75.414089,42.312895],[-74.844488,42.510065]]]}}, -{"type":"Feature","id":"36027","properties":{"name":"Dutchess"},"geometry":{"type":"Polygon","coordinates":[[[-73.929839,42.077386],[-73.49716,42.050002],[-73.486206,42.050002],[-73.519068,41.666616],[-73.530022,41.529692],[-73.979131,41.436584],[-73.951746,41.589939],[-73.929839,42.077386]]]}}, -{"type":"Feature","id":"36029","properties":{"name":"Erie"},"geometry":{"type":"Polygon","coordinates":[[[-78.552376,43.096097],[-78.464745,43.09062],[-78.464745,42.866066],[-78.464745,42.537449],[-79.001485,42.531973],[-79.061732,42.537449],[-79.138409,42.570311],[-79.138409,42.570311],[-79.023393,43.068713],[-78.552376,43.096097]]]}}, -{"type":"Feature","id":"36031","properties":{"name":"Essex"},"geometry":{"type":"Polygon","coordinates":[[[-73.338329,44.547487],[-73.310944,44.262686],[-73.376668,43.8081],[-73.436914,43.802623],[-73.853161,43.764284],[-74.055808,43.742376],[-74.280363,44.120285],[-73.907931,44.426994],[-73.338329,44.547487]]]}}, -{"type":"Feature","id":"36033","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-74.028424,44.996596],[-73.907931,44.426994],[-74.280363,44.120285],[-74.537779,44.098377],[-74.723995,44.996596],[-74.028424,44.996596]]]}}, -{"type":"Feature","id":"36035","properties":{"name":"Fulton"},"geometry":{"type":"Polygon","coordinates":[[[-74.713041,43.28779],[-74.137962,43.254929],[-74.099624,42.981082],[-74.581595,42.997512],[-74.762334,43.046805],[-74.713041,43.28779]]]}}, -{"type":"Feature","id":"36037","properties":{"name":"Genesee"},"geometry":{"type":"Polygon","coordinates":[[[-77.906097,43.128959],[-77.911574,42.986559],[-77.95539,42.860589],[-78.09779,42.871543],[-78.464745,42.866066],[-78.464745,43.09062],[-78.464745,43.128959],[-77.999205,43.134436],[-77.906097,43.128959]]]}}, -{"type":"Feature","id":"36039","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-73.781961,42.466249],[-73.913408,42.126679],[-74.01747,42.159541],[-74.450148,42.170494],[-74.444671,42.35671],[-74.252978,42.406003],[-73.781961,42.466249]]]}}, -{"type":"Feature","id":"36041","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-74.280363,44.120285],[-74.055808,43.742376],[-74.15987,43.369944],[-74.137962,43.254929],[-74.713041,43.28779],[-74.855442,44.070993],[-74.537779,44.098377],[-74.280363,44.120285]]]}}, -{"type":"Feature","id":"36043","properties":{"name":"Herkimer"},"geometry":{"type":"Polygon","coordinates":[[[-75.167627,44.098377],[-74.855442,44.070993],[-74.713041,43.28779],[-74.762334,43.046805],[-74.762334,42.860589],[-75.096427,42.904404],[-75.211443,42.882497],[-75.112858,43.616407],[-75.167627,44.098377]]]}}, -{"type":"Feature","id":"36045","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-75.857722,44.405086],[-75.446951,44.21887],[-75.775568,43.687607],[-76.087753,43.671176],[-76.202769,43.68213],[-76.312308,44.196962],[-75.857722,44.405086]]]}}, -{"type":"Feature","id":"36047","properties":{"name":"Kings"},"geometry":{"type":"Polygon","coordinates":[[[-73.951746,40.741013],[-73.940792,40.565751],[-74.022947,40.680767],[-73.9627,40.735536],[-73.951746,40.741013]]]}}, -{"type":"Feature","id":"36049","properties":{"name":"Lewis"},"geometry":{"type":"Polygon","coordinates":[[[-75.446951,44.21887],[-75.167627,44.098377],[-75.112858,43.616407],[-75.75366,43.468529],[-75.775568,43.687607],[-75.446951,44.21887]]]}}, -{"type":"Feature","id":"36051","properties":{"name":"Livingston"},"geometry":{"type":"Polygon","coordinates":[[[-77.823943,42.986559],[-77.582958,42.942743],[-77.48985,42.575788],[-77.648681,42.581265],[-77.725358,42.471726],[-78.037544,42.521019],[-77.95539,42.860589],[-77.911574,42.986559],[-77.823943,42.986559]]]}}, -{"type":"Feature","id":"36053","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-75.978214,43.167298],[-75.994645,43.183728],[-75.885106,43.156344],[-75.249781,42.871543],[-75.293597,42.745573],[-75.310028,42.745573],[-75.890583,42.723665],[-75.89606,42.789389],[-75.978214,43.167298]]]}}, -{"type":"Feature","id":"36055","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-77.374834,43.276836],[-77.369357,43.035851],[-77.582958,42.942743],[-77.823943,42.986559],[-77.911574,42.986559],[-77.906097,43.128959],[-77.999205,43.134436],[-77.993728,43.364467],[-77.374834,43.276836]]]}}, -{"type":"Feature","id":"36057","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-74.581595,42.997512],[-74.099624,42.981082],[-74.094147,42.953697],[-74.263932,42.794866],[-74.647318,42.827727],[-74.762334,42.860589],[-74.762334,43.046805],[-74.581595,42.997512]]]}}, -{"type":"Feature","id":"36059","properties":{"name":"Nassau"},"geometry":{"type":"Polygon","coordinates":[[[-73.49716,40.921752],[-73.42596,40.609566],[-73.754577,40.587659],[-73.76553,40.801259],[-73.49716,40.921752]]]}}, -{"type":"Feature","id":"36061","properties":{"name":"New York"},"geometry":{"type":"Polygon","coordinates":[[[-73.924362,40.877937],[-73.913408,40.795782],[-73.9627,40.735536],[-74.022947,40.680767],[-74.022947,40.708151],[-73.984608,40.795782],[-73.935316,40.883413],[-73.924362,40.877937]]]}}, -{"type":"Feature","id":"36063","properties":{"name":"Niagara"},"geometry":{"type":"Polygon","coordinates":[[[-78.464745,43.369944],[-78.464745,43.128959],[-78.464745,43.09062],[-78.552376,43.096097],[-79.023393,43.068713],[-78.464745,43.369944]]]}}, -{"type":"Feature","id":"36065","properties":{"name":"Oneida"},"geometry":{"type":"Polygon","coordinates":[[[-75.112858,43.616407],[-75.211443,42.882497],[-75.249781,42.871543],[-75.885106,43.156344],[-75.75366,43.468529],[-75.112858,43.616407]]]}}, -{"type":"Feature","id":"36067","properties":{"name":"Onondaga"},"geometry":{"type":"Polygon","coordinates":[[[-76.169907,43.249452],[-75.994645,43.183728],[-75.978214,43.167298],[-75.89606,42.789389],[-75.917968,42.789389],[-76.273969,42.772958],[-76.476616,43.227544],[-76.169907,43.249452]]]}}, -{"type":"Feature","id":"36069","properties":{"name":"Ontario"},"geometry":{"type":"Polygon","coordinates":[[[-77.122895,43.013943],[-76.964064,43.013943],[-76.975017,42.762004],[-77.36388,42.575788],[-77.48985,42.575788],[-77.582958,42.942743],[-77.369357,43.035851],[-77.122895,43.013943]]]}}, -{"type":"Feature","id":"36071","properties":{"name":"Orange"},"geometry":{"type":"Polygon","coordinates":[[[-74.263932,41.633754],[-73.951746,41.589939],[-73.979131,41.436584],[-73.979131,41.327046],[-74.236547,41.14083],[-74.367994,41.201076],[-74.69661,41.359907],[-74.756857,41.425631],[-74.367994,41.589939],[-74.263932,41.633754]]]}}, -{"type":"Feature","id":"36073","properties":{"name":"Orleans"},"geometry":{"type":"Polygon","coordinates":[[[-77.993728,43.364467],[-77.999205,43.134436],[-78.464745,43.128959],[-78.464745,43.369944],[-77.993728,43.364467]]]}}, -{"type":"Feature","id":"36075","properties":{"name":"Oswego"},"geometry":{"type":"Polygon","coordinates":[[[-76.087753,43.671176],[-75.775568,43.687607],[-75.75366,43.468529],[-75.885106,43.156344],[-75.994645,43.183728],[-76.169907,43.249452],[-76.476616,43.227544],[-76.619016,43.419237],[-76.202769,43.68213],[-76.087753,43.671176]]]}}, -{"type":"Feature","id":"36077","properties":{"name":"Otsego"},"geometry":{"type":"Polygon","coordinates":[[[-75.096427,42.904404],[-74.762334,42.860589],[-74.647318,42.827727],[-74.713041,42.515542],[-74.844488,42.510065],[-75.414089,42.312895],[-75.293597,42.745573],[-75.249781,42.871543],[-75.211443,42.882497],[-75.096427,42.904404]]]}}, -{"type":"Feature","id":"36079","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-73.530022,41.529692],[-73.546453,41.365384],[-73.661469,41.35443],[-73.984608,41.321569],[-73.979131,41.327046],[-73.979131,41.436584],[-73.530022,41.529692]]]}}, -{"type":"Feature","id":"36081","properties":{"name":"Queens"},"geometry":{"type":"Polygon","coordinates":[[[-73.814823,40.806736],[-73.787438,40.801259],[-73.76553,40.801259],[-73.754577,40.587659],[-73.940792,40.565751],[-73.951746,40.741013],[-73.9627,40.735536],[-73.913408,40.795782],[-73.814823,40.806736]]]}}, -{"type":"Feature","id":"36083","properties":{"name":"Rensselaer"},"geometry":{"type":"Polygon","coordinates":[[[-73.387622,42.94822],[-73.272606,42.942743],[-73.267129,42.745573],[-73.35476,42.510065],[-73.398575,42.504588],[-73.781961,42.466249],[-73.677899,42.783912],[-73.634084,42.942743],[-73.387622,42.94822]]]}}, -{"type":"Feature","id":"36087","properties":{"name":"Rockland"},"geometry":{"type":"Polygon","coordinates":[[[-73.984608,41.321569],[-73.8915,40.998429],[-74.21464,41.135353],[-74.236547,41.14083],[-73.979131,41.327046],[-73.984608,41.321569]]]}}, -{"type":"Feature","id":"36089","properties":{"name":"St. Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-74.723995,44.996596],[-74.537779,44.098377],[-74.855442,44.070993],[-75.167627,44.098377],[-75.446951,44.21887],[-75.857722,44.405086],[-75.238827,44.865149],[-74.723995,44.996596]]]}}, -{"type":"Feature","id":"36091","properties":{"name":"Saratoga"},"geometry":{"type":"Polygon","coordinates":[[[-73.886023,43.397329],[-73.595745,43.304221],[-73.634084,42.942743],[-73.677899,42.783912],[-73.809346,42.778435],[-74.094147,42.953697],[-74.099624,42.981082],[-74.137962,43.254929],[-74.15987,43.369944],[-73.886023,43.397329]]]}}, -{"type":"Feature","id":"36093","properties":{"name":"Schenectady"},"geometry":{"type":"Polygon","coordinates":[[[-74.094147,42.953697],[-73.809346,42.778435],[-74.181778,42.729142],[-74.263932,42.794866],[-74.094147,42.953697]]]}}, -{"type":"Feature","id":"36095","properties":{"name":"Schoharie"},"geometry":{"type":"Polygon","coordinates":[[[-74.647318,42.827727],[-74.263932,42.794866],[-74.181778,42.729142],[-74.252978,42.406003],[-74.444671,42.35671],[-74.713041,42.515542],[-74.647318,42.827727]]]}}, -{"type":"Feature","id":"36097","properties":{"name":"Schuyler"},"geometry":{"type":"Polygon","coordinates":[[[-76.70117,42.548403],[-76.695693,42.548403],[-76.619016,42.28551],[-76.766894,42.296464],[-76.964064,42.280033],[-77.106464,42.48268],[-76.892863,42.542926],[-76.70117,42.548403]]]}}, -{"type":"Feature","id":"36099","properties":{"name":"Seneca"},"geometry":{"type":"Polygon","coordinates":[[[-76.712124,43.024897],[-76.668309,42.625081],[-76.695693,42.548403],[-76.70117,42.548403],[-76.892863,42.542926],[-76.975017,42.762004],[-76.964064,43.013943],[-76.712124,43.024897]]]}}, -{"type":"Feature","id":"36101","properties":{"name":"Steuben"},"geometry":{"type":"Polygon","coordinates":[[[-77.648681,42.581265],[-77.48985,42.575788],[-77.36388,42.575788],[-77.106464,42.48268],[-76.964064,42.280033],[-76.964064,42.000709],[-77.610343,42.000709],[-77.747266,42.000709],[-77.725358,42.471726],[-77.648681,42.581265]]]}}, -{"type":"Feature","id":"36103","properties":{"name":"Suffolk"},"geometry":{"type":"Polygon","coordinates":[[[-73.42596,40.609566],[-73.49716,40.921752],[-72.100541,40.992952],[-73.42596,40.609566]]]}}, -{"type":"Feature","id":"36105","properties":{"name":"Sullivan"},"geometry":{"type":"Polygon","coordinates":[[[-74.789718,42.011663],[-74.778764,42.01714],[-74.367994,41.589939],[-74.756857,41.425631],[-75.069042,41.600893],[-75.145719,41.852832],[-74.789718,42.011663]]]}}, -{"type":"Feature","id":"36107","properties":{"name":"Tioga"},"geometry":{"type":"Polygon","coordinates":[[[-76.131569,42.41148],[-76.104184,42.000709],[-76.147999,42.000709],[-76.55877,42.000709],[-76.536862,42.280033],[-76.252061,42.406003],[-76.131569,42.41148]]]}}, -{"type":"Feature","id":"36109","properties":{"name":"Tompkins"},"geometry":{"type":"Polygon","coordinates":[[[-76.460185,42.625081],[-76.263015,42.625081],[-76.252061,42.406003],[-76.536862,42.280033],[-76.619016,42.28551],[-76.695693,42.548403],[-76.668309,42.625081],[-76.460185,42.625081]]]}}, -{"type":"Feature","id":"36111","properties":{"name":"Ulster"},"geometry":{"type":"Polygon","coordinates":[[[-74.01747,42.159541],[-73.913408,42.126679],[-73.929839,42.077386],[-73.951746,41.589939],[-74.263932,41.633754],[-74.367994,41.589939],[-74.778764,42.01714],[-74.450148,42.170494],[-74.01747,42.159541]]]}}, -{"type":"Feature","id":"36113","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-73.853161,43.764284],[-73.436914,43.802623],[-73.595745,43.304221],[-73.886023,43.397329],[-74.15987,43.369944],[-74.055808,43.742376],[-73.853161,43.764284]]]}}, -{"type":"Feature","id":"36115","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-73.376668,43.8081],[-73.365714,43.75333],[-73.256175,43.315175],[-73.272606,42.942743],[-73.387622,42.94822],[-73.634084,42.942743],[-73.595745,43.304221],[-73.436914,43.802623],[-73.376668,43.8081]]]}}, -{"type":"Feature","id":"36117","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-76.723078,43.34256],[-76.712124,43.024897],[-76.964064,43.013943],[-77.122895,43.013943],[-77.369357,43.035851],[-77.374834,43.276836],[-76.723078,43.34256]]]}}, -{"type":"Feature","id":"36119","properties":{"name":"Westchester"},"geometry":{"type":"Polygon","coordinates":[[[-73.661469,41.35443],[-73.546453,41.365384],[-73.655992,40.987475],[-73.781961,40.883413],[-73.918885,40.916275],[-73.8915,40.998429],[-73.984608,41.321569],[-73.661469,41.35443]]]}}, -{"type":"Feature","id":"36121","properties":{"name":"Wyoming"},"geometry":{"type":"Polygon","coordinates":[[[-78.09779,42.871543],[-77.95539,42.860589],[-78.037544,42.521019],[-78.22376,42.521019],[-78.311391,42.521019],[-78.464745,42.537449],[-78.464745,42.866066],[-78.09779,42.871543]]]}}, -{"type":"Feature","id":"36123","properties":{"name":"Yates"},"geometry":{"type":"Polygon","coordinates":[[[-76.975017,42.762004],[-76.892863,42.542926],[-77.106464,42.48268],[-77.36388,42.575788],[-76.975017,42.762004]]]}}, -{"type":"Feature","id":"37001","properties":{"name":"Alamance"},"geometry":{"type":"Polygon","coordinates":[[[-79.532749,36.249922],[-79.258902,36.244445],[-79.247948,35.87749],[-79.543702,35.844628],[-79.543702,35.899398],[-79.532749,36.238968],[-79.532749,36.249922]]]}}, -{"type":"Feature","id":"37003","properties":{"name":"Alexander"},"geometry":{"type":"Polygon","coordinates":[[[-81.027953,36.047275],[-81.110107,35.778905],[-81.192262,35.822721],[-81.334662,35.795336],[-81.329185,35.997983],[-81.027953,36.047275]]]}}, -{"type":"Feature","id":"37005","properties":{"name":"Alleghany"},"geometry":{"type":"Polygon","coordinates":[[[-80.978661,36.562108],[-80.901984,36.562108],[-80.967707,36.403276],[-81.082723,36.430661],[-81.252508,36.364938],[-81.351093,36.573061],[-80.978661,36.562108]]]}}, -{"type":"Feature","id":"37007","properties":{"name":"Anson"},"geometry":{"type":"Polygon","coordinates":[[[-80.173551,35.149057],[-80.074966,35.14358],[-79.927088,34.80401],[-80.321428,34.814964],[-80.277612,35.198349],[-80.173551,35.149057]]]}}, -{"type":"Feature","id":"37009","properties":{"name":"Ashe"},"geometry":{"type":"Polygon","coordinates":[[[-81.351093,36.573061],[-81.252508,36.364938],[-81.477062,36.238968],[-81.734479,36.392322],[-81.679709,36.589492],[-81.351093,36.573061]]]}}, -{"type":"Feature","id":"37011","properties":{"name":"Avery"},"geometry":{"type":"Polygon","coordinates":[[[-81.931648,36.266353],[-81.920695,36.288261],[-81.811156,36.112998],[-81.805679,35.959644],[-81.898787,35.997983],[-81.942602,35.959644],[-81.948079,35.954167],[-81.980941,35.910352],[-82.079526,36.107521],[-81.931648,36.266353]]]}}, -{"type":"Feature","id":"37013","properties":{"name":"Beaufort"},"geometry":{"type":"Polygon","coordinates":[[[-77.172187,35.73509],[-76.843571,35.707705],[-76.640924,35.707705],[-76.547816,35.390042],[-76.602586,35.335273],[-76.624493,35.253119],[-76.89834,35.253119],[-77.188618,35.417427],[-77.172187,35.73509]]]}}, -{"type":"Feature","id":"37015","properties":{"name":"Bertie"},"geometry":{"type":"Polygon","coordinates":[[[-76.706647,36.244445],[-76.668309,36.01989],[-76.690217,35.943213],[-76.761417,35.866536],[-77.325542,36.07466],[-77.29268,36.167768],[-77.210526,36.244445],[-76.706647,36.244445]]]}}, -{"type":"Feature","id":"37017","properties":{"name":"Bladen"},"geometry":{"type":"Polygon","coordinates":[[[-78.49213,34.847825],[-78.256622,34.55207],[-78.256622,34.398716],[-78.870039,34.48087],[-78.9029,34.836871],[-78.49213,34.858779],[-78.49213,34.847825]]]}}, -{"type":"Feature","id":"37019","properties":{"name":"Brunswick"},"geometry":{"type":"Polygon","coordinates":[[[-78.125175,34.365854],[-78.032067,34.332993],[-77.938959,33.927699],[-78.541422,33.851022],[-78.650961,33.94413],[-78.163514,34.354901],[-78.125175,34.365854]]]}}, -{"type":"Feature","id":"37021","properties":{"name":"Buncombe"},"geometry":{"type":"Polygon","coordinates":[[[-82.276696,35.702228],[-82.167157,35.526966],[-82.265742,35.466719],[-82.408142,35.472196],[-82.747713,35.422904],[-82.884636,35.68032],[-82.408142,35.817244],[-82.276696,35.702228]]]}}, -{"type":"Feature","id":"37023","properties":{"name":"Burke"},"geometry":{"type":"Polygon","coordinates":[[[-81.898787,35.997983],[-81.805679,35.959644],[-81.362047,35.767951],[-81.531832,35.570781],[-81.537309,35.565304],[-81.586601,35.565304],[-81.690663,35.581735],[-81.82211,35.576258],[-81.942602,35.959644],[-81.898787,35.997983]]]}}, -{"type":"Feature","id":"37025","properties":{"name":"Cabarrus"},"geometry":{"type":"Polygon","coordinates":[[[-80.737675,35.505058],[-80.294043,35.505058],[-80.507644,35.187396],[-80.55146,35.209303],[-80.781491,35.505058],[-80.737675,35.505058]]]}}, -{"type":"Feature","id":"37027","properties":{"name":"Caldwell"},"geometry":{"type":"Polygon","coordinates":[[[-81.685186,36.123952],[-81.542786,36.118475],[-81.329185,35.997983],[-81.334662,35.795336],[-81.362047,35.767951],[-81.805679,35.959644],[-81.811156,36.112998],[-81.685186,36.123952]]]}}, -{"type":"Feature","id":"37029","properties":{"name":"Camden"},"geometry":{"type":"Polygon","coordinates":[[[-76.493047,36.551154],[-76.312308,36.551154],[-75.885106,36.162291],[-76.049415,36.184199],[-76.493047,36.512815],[-76.542339,36.551154],[-76.493047,36.551154]]]}}, -{"type":"Feature","id":"37031","properties":{"name":"Carteret"},"geometry":{"type":"Polygon","coordinates":[[[-77.111941,34.639701],[-77.16671,34.787579],[-77.090033,34.80401],[-76.712124,34.979272],[-76.646401,35.01761],[-76.279446,34.940933],[-76.536862,34.590409],[-77.111941,34.639701]]]}}, -{"type":"Feature","id":"37033","properties":{"name":"Caswell"},"geometry":{"type":"Polygon","coordinates":[[[-79.138409,36.5402],[-79.15484,36.244445],[-79.247948,36.244445],[-79.258902,36.244445],[-79.532749,36.249922],[-79.510841,36.5402],[-79.472502,36.5402],[-79.341056,36.5402],[-79.220563,36.5402],[-79.138409,36.5402]]]}}, -{"type":"Feature","id":"37035","properties":{"name":"Catawba"},"geometry":{"type":"Polygon","coordinates":[[[-81.192262,35.822721],[-81.110107,35.778905],[-80.96223,35.548874],[-81.488016,35.570781],[-81.531832,35.570781],[-81.362047,35.767951],[-81.334662,35.795336],[-81.192262,35.822721]]]}}, -{"type":"Feature","id":"37037","properties":{"name":"Chatham"},"geometry":{"type":"Polygon","coordinates":[[[-79.187701,35.872013],[-79.017916,35.861059],[-78.908377,35.866536],[-78.913854,35.581735],[-78.968624,35.521489],[-79.242471,35.570781],[-79.35201,35.516012],[-79.554656,35.516012],[-79.543702,35.844628],[-79.247948,35.87749],[-79.187701,35.872013]]]}}, -{"type":"Feature","id":"37039","properties":{"name":"Cherokee"},"geometry":{"type":"Polygon","coordinates":[[[-83.7007,35.247642],[-83.739039,35.154534],[-84.007409,34.984749],[-84.127902,34.990226],[-84.319594,34.990226],[-84.29221,35.209303],[-84.029317,35.291457],[-83.7007,35.247642]]]}}, -{"type":"Feature","id":"37041","properties":{"name":"Chowan"},"geometry":{"type":"Polygon","coordinates":[[[-76.695693,36.293737],[-76.55877,36.353984],[-76.410893,36.07466],[-76.668309,36.01989],[-76.706647,36.244445],[-76.695693,36.293737]]]}}, -{"type":"Feature","id":"37043","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-83.739039,35.154534],[-83.481623,34.995703],[-83.547346,34.990226],[-83.936209,34.984749],[-84.007409,34.984749],[-83.739039,35.154534]]]}}, -{"type":"Feature","id":"37045","properties":{"name":"Cleveland"},"geometry":{"type":"Polygon","coordinates":[[[-81.586601,35.565304],[-81.537309,35.565304],[-81.455155,35.417427],[-81.329185,35.165488],[-81.367524,35.165488],[-81.76734,35.181919],[-81.690663,35.581735],[-81.586601,35.565304]]]}}, -{"type":"Feature","id":"37047","properties":{"name":"Columbus"},"geometry":{"type":"Polygon","coordinates":[[[-78.870039,34.48087],[-78.256622,34.398716],[-78.163514,34.354901],[-78.650961,33.94413],[-79.072686,34.300131],[-78.870039,34.48087]]]}}, -{"type":"Feature","id":"37049","properties":{"name":"Craven"},"geometry":{"type":"Polygon","coordinates":[[[-77.188618,35.417427],[-76.89834,35.253119],[-76.712124,34.979272],[-77.090033,34.80401],[-77.473419,35.231211],[-77.391265,35.34075],[-77.188618,35.417427]]]}}, -{"type":"Feature","id":"37051","properties":{"name":"Cumberland"},"geometry":{"type":"Polygon","coordinates":[[[-78.952193,35.21478],[-78.6181,35.247642],[-78.49213,34.858779],[-78.9029,34.836871],[-79.034347,34.951887],[-79.10007,35.176442],[-79.094593,35.192872],[-78.952193,35.21478]]]}}, -{"type":"Feature","id":"37053","properties":{"name":"Currituck"},"geometry":{"type":"Polygon","coordinates":[[[-75.901537,36.551154],[-75.868676,36.551154],[-75.775568,36.233491],[-75.791998,36.228014],[-75.885106,36.162291],[-76.312308,36.551154],[-76.120615,36.551154],[-75.901537,36.551154]]]}}, -{"type":"Feature","id":"37055","properties":{"name":"Dare"},"geometry":{"type":"Polygon","coordinates":[[[-75.868676,35.581735],[-76.027507,35.669366],[-76.000122,35.904875],[-75.868676,35.581735]]]}}, -{"type":"Feature","id":"37057","properties":{"name":"Davidson"},"geometry":{"type":"Polygon","coordinates":[[[-80.211889,36.008937],[-80.042104,36.008937],[-80.047581,35.921306],[-80.064012,35.505058],[-80.184505,35.505058],[-80.458352,35.740566],[-80.398105,35.970598],[-80.211889,36.008937]]]}}, -{"type":"Feature","id":"37059","properties":{"name":"Davie"},"geometry":{"type":"Polygon","coordinates":[[[-80.69386,36.052752],[-80.49669,36.047275],[-80.398105,35.970598],[-80.458352,35.740566],[-80.688383,35.861059],[-80.710291,35.850105],[-80.69386,36.052752]]]}}, -{"type":"Feature","id":"37061","properties":{"name":"Duplin"},"geometry":{"type":"Polygon","coordinates":[[[-78.043021,35.192872],[-77.834897,35.176442],[-77.730835,35.006656],[-77.676066,34.973795],[-77.681543,34.721856],[-78.015636,34.732809],[-78.114221,34.721856],[-78.163514,35.187396],[-78.043021,35.192872]]]}}, -{"type":"Feature","id":"37063","properties":{"name":"Durham"},"geometry":{"type":"Polygon","coordinates":[[[-78.952193,36.238968],[-78.804316,36.233491],[-78.749546,36.069183],[-78.908377,35.866536],[-79.017916,35.861059],[-78.952193,36.238968]]]}}, -{"type":"Feature","id":"37065","properties":{"name":"Edgecombe"},"geometry":{"type":"Polygon","coordinates":[[[-77.697974,36.151337],[-77.402219,36.00346],[-77.352926,35.817244],[-77.413173,35.822721],[-77.659635,35.674843],[-77.82942,35.866536],[-77.82942,35.866536],[-77.697974,36.151337]]]}}, -{"type":"Feature","id":"37067","properties":{"name":"Forsyth"},"geometry":{"type":"Polygon","coordinates":[[[-80.452875,36.260876],[-80.036627,36.255399],[-80.042104,36.008937],[-80.211889,36.008937],[-80.398105,35.970598],[-80.49669,36.047275],[-80.452875,36.238968],[-80.452875,36.260876]]]}}, -{"type":"Feature","id":"37069","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-78.163514,36.249922],[-78.004682,36.200629],[-78.053975,36.134906],[-78.256622,35.817244],[-78.546899,36.01989],[-78.497607,36.173245],[-78.305914,36.266353],[-78.163514,36.249922]]]}}, -{"type":"Feature","id":"37071","properties":{"name":"Gaston"},"geometry":{"type":"Polygon","coordinates":[[[-81.455155,35.417427],[-80.956753,35.400996],[-81.044384,35.149057],[-81.329185,35.165488],[-81.455155,35.417427]]]}}, -{"type":"Feature","id":"37073","properties":{"name":"Gates"},"geometry":{"type":"Polygon","coordinates":[[[-76.914771,36.551154],[-76.542339,36.551154],[-76.493047,36.512815],[-76.454708,36.375892],[-76.55877,36.353984],[-76.695693,36.293737],[-76.914771,36.545677],[-76.914771,36.551154]]]}}, -{"type":"Feature","id":"37075","properties":{"name":"Graham"},"geometry":{"type":"Polygon","coordinates":[[[-83.952639,35.461243],[-83.678792,35.280503],[-83.7007,35.247642],[-84.029317,35.291457],[-83.963593,35.461243],[-83.952639,35.461243]]]}}, -{"type":"Feature","id":"37077","properties":{"name":"Granville"},"geometry":{"type":"Polygon","coordinates":[[[-78.470222,36.5402],[-78.459268,36.5402],[-78.497607,36.173245],[-78.546899,36.01989],[-78.749546,36.069183],[-78.804316,36.233491],[-78.798839,36.5402],[-78.733115,36.5402],[-78.470222,36.5402]]]}}, -{"type":"Feature","id":"37079","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-77.681543,35.636505],[-77.473419,35.428381],[-77.807512,35.368135],[-77.823943,35.570781],[-77.697974,35.652935],[-77.681543,35.636505]]]}}, -{"type":"Feature","id":"37081","properties":{"name":"Guilford"},"geometry":{"type":"Polygon","coordinates":[[[-80.036627,36.255399],[-80.036627,36.255399],[-79.532749,36.238968],[-79.543702,35.899398],[-80.036627,35.921306],[-80.047581,35.921306],[-80.042104,36.008937],[-80.036627,36.255399]]]}}, -{"type":"Feature","id":"37083","properties":{"name":"Halifax"},"geometry":{"type":"Polygon","coordinates":[[[-77.90062,36.507338],[-77.29268,36.167768],[-77.325542,36.07466],[-77.402219,36.00346],[-77.697974,36.151337],[-78.004682,36.200629],[-77.90062,36.507338]]]}}, -{"type":"Feature","id":"37085","properties":{"name":"Harnett"},"geometry":{"type":"Polygon","coordinates":[[[-78.913854,35.581735],[-78.711208,35.521489],[-78.541422,35.313365],[-78.6181,35.247642],[-78.952193,35.21478],[-79.094593,35.192872],[-79.182224,35.307888],[-78.968624,35.521489],[-78.913854,35.581735]]]}}, -{"type":"Feature","id":"37087","properties":{"name":"Haywood"},"geometry":{"type":"Polygon","coordinates":[[[-82.961313,35.789859],[-82.884636,35.68032],[-82.747713,35.422904],[-82.922975,35.291457],[-83.185868,35.516012],[-83.257068,35.696751],[-83.257068,35.713182],[-82.961313,35.789859]]]}}, -{"type":"Feature","id":"37089","properties":{"name":"Henderson"},"geometry":{"type":"Polygon","coordinates":[[[-82.408142,35.472196],[-82.265742,35.466719],[-82.260265,35.395519],[-82.353373,35.192872],[-82.572451,35.14358],[-82.747713,35.422904],[-82.408142,35.472196]]]}}, -{"type":"Feature","id":"37091","properties":{"name":"Hertford"},"geometry":{"type":"Polygon","coordinates":[[[-76.914771,36.545677],[-76.695693,36.293737],[-76.706647,36.244445],[-77.210526,36.244445],[-77.16671,36.545677],[-76.914771,36.545677]]]}}, -{"type":"Feature","id":"37093","properties":{"name":"Hoke"},"geometry":{"type":"Polygon","coordinates":[[[-79.127455,35.165488],[-79.10007,35.176442],[-79.034347,34.951887],[-79.346533,34.836871],[-79.461548,35.044995],[-79.127455,35.165488]]]}}, -{"type":"Feature","id":"37095","properties":{"name":"Hyde"},"geometry":{"type":"Polygon","coordinates":[[[-76.635447,35.707705],[-76.394462,35.696751],[-76.027507,35.669366],[-75.868676,35.581735],[-76.547816,35.390042],[-76.640924,35.707705],[-76.635447,35.707705]]]}}, -{"type":"Feature","id":"37097","properties":{"name":"Iredell"},"geometry":{"type":"Polygon","coordinates":[[[-80.880076,36.058229],[-80.69386,36.052752],[-80.710291,35.850105],[-80.737675,35.505058],[-80.781491,35.505058],[-80.907461,35.516012],[-80.945799,35.488627],[-80.96223,35.548874],[-81.110107,35.778905],[-81.027953,36.047275],[-80.880076,36.058229]]]}}, -{"type":"Feature","id":"37099","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-83.207776,35.516012],[-83.185868,35.516012],[-82.922975,35.291457],[-83.010606,35.028564],[-83.109191,35.00118],[-83.339222,35.329796],[-83.207776,35.516012]]]}}, -{"type":"Feature","id":"37101","properties":{"name":"Johnston"},"geometry":{"type":"Polygon","coordinates":[[[-78.256622,35.817244],[-78.190898,35.729613],[-78.064929,35.587212],[-78.305914,35.28598],[-78.541422,35.313365],[-78.711208,35.521489],[-78.256622,35.817244]]]}}, -{"type":"Feature","id":"37103","properties":{"name":"Jones"},"geometry":{"type":"Polygon","coordinates":[[[-77.473419,35.231211],[-77.090033,34.80401],[-77.16671,34.787579],[-77.676066,34.973795],[-77.730835,35.006656],[-77.473419,35.231211]]]}}, -{"type":"Feature","id":"37105","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-79.242471,35.570781],[-78.968624,35.521489],[-79.182224,35.307888],[-79.35201,35.516012],[-79.242471,35.570781]]]}}, -{"type":"Feature","id":"37107","properties":{"name":"Lenoir"},"geometry":{"type":"Polygon","coordinates":[[[-77.446034,35.379088],[-77.391265,35.34075],[-77.473419,35.231211],[-77.730835,35.006656],[-77.834897,35.176442],[-77.807512,35.368135],[-77.473419,35.428381],[-77.446034,35.379088]]]}}, -{"type":"Feature","id":"37109","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-81.488016,35.570781],[-80.96223,35.548874],[-80.945799,35.488627],[-80.956753,35.400996],[-81.455155,35.417427],[-81.537309,35.565304],[-81.531832,35.570781],[-81.488016,35.570781]]]}}, -{"type":"Feature","id":"37111","properties":{"name":"McDowell"},"geometry":{"type":"Polygon","coordinates":[[[-81.948079,35.954167],[-81.942602,35.959644],[-81.82211,35.576258],[-82.167157,35.526966],[-82.276696,35.702228],[-82.134295,35.822721],[-81.980941,35.910352],[-81.948079,35.954167]]]}}, -{"type":"Feature","id":"37113","properties":{"name":"Macon"},"geometry":{"type":"Polygon","coordinates":[[[-83.339222,35.329796],[-83.109191,35.00118],[-83.481623,34.995703],[-83.739039,35.154534],[-83.7007,35.247642],[-83.678792,35.280503],[-83.339222,35.329796]]]}}, -{"type":"Feature","id":"37115","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-82.786051,35.987029],[-82.605312,36.041798],[-82.506727,35.976075],[-82.408142,35.817244],[-82.884636,35.68032],[-82.961313,35.789859],[-82.901067,35.943213],[-82.786051,35.987029]]]}}, -{"type":"Feature","id":"37117","properties":{"name":"Martin"},"geometry":{"type":"Polygon","coordinates":[[[-77.325542,36.07466],[-76.761417,35.866536],[-76.843571,35.707705],[-77.172187,35.73509],[-77.352926,35.817244],[-77.402219,36.00346],[-77.325542,36.07466]]]}}, -{"type":"Feature","id":"37119","properties":{"name":"Mecklenburg"},"geometry":{"type":"Polygon","coordinates":[[[-80.907461,35.516012],[-80.781491,35.505058],[-80.55146,35.209303],[-80.841737,35.00118],[-80.907461,35.077857],[-81.044384,35.149057],[-80.956753,35.400996],[-80.945799,35.488627],[-80.907461,35.516012]]]}}, -{"type":"Feature","id":"37121","properties":{"name":"Mitchell"},"geometry":{"type":"Polygon","coordinates":[[[-82.079526,36.107521],[-81.980941,35.910352],[-82.134295,35.822721],[-82.419096,36.07466],[-82.221926,36.156814],[-82.079526,36.107521]]]}}, -{"type":"Feature","id":"37123","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-79.768257,35.510535],[-79.614903,35.165488],[-79.729918,35.176442],[-80.074966,35.14358],[-80.184505,35.505058],[-80.064012,35.505058],[-79.768257,35.510535]]]}}, -{"type":"Feature","id":"37125","properties":{"name":"Moore"},"geometry":{"type":"Polygon","coordinates":[[[-79.35201,35.516012],[-79.182224,35.307888],[-79.094593,35.192872],[-79.10007,35.176442],[-79.127455,35.165488],[-79.461548,35.044995],[-79.614903,35.165488],[-79.768257,35.510535],[-79.554656,35.516012],[-79.35201,35.516012]]]}}, -{"type":"Feature","id":"37127","properties":{"name":"Nash"},"geometry":{"type":"Polygon","coordinates":[[[-78.053975,36.134906],[-78.004682,36.200629],[-77.697974,36.151337],[-77.82942,35.866536],[-78.190898,35.729613],[-78.256622,35.817244],[-78.053975,36.134906]]]}}, -{"type":"Feature","id":"37129","properties":{"name":"New Hanover"},"geometry":{"type":"Polygon","coordinates":[[[-77.960867,34.376808],[-77.714404,34.294654],[-77.938959,33.927699],[-78.032067,34.332993],[-77.960867,34.376808]]]}}, -{"type":"Feature","id":"37131","properties":{"name":"Northampton"},"geometry":{"type":"Polygon","coordinates":[[[-77.298157,36.545677],[-77.16671,36.545677],[-77.210526,36.244445],[-77.29268,36.167768],[-77.90062,36.507338],[-77.90062,36.545677],[-77.769174,36.545677],[-77.298157,36.545677]]]}}, -{"type":"Feature","id":"37133","properties":{"name":"Onslow"},"geometry":{"type":"Polygon","coordinates":[[[-77.676066,34.973795],[-77.16671,34.787579],[-77.111941,34.639701],[-77.517235,34.442532],[-77.681543,34.721856],[-77.676066,34.973795]]]}}, -{"type":"Feature","id":"37135","properties":{"name":"Orange"},"geometry":{"type":"Polygon","coordinates":[[[-79.247948,36.244445],[-79.15484,36.244445],[-78.952193,36.238968],[-79.017916,35.861059],[-79.187701,35.872013],[-79.247948,35.87749],[-79.258902,36.244445],[-79.247948,36.244445]]]}}, -{"type":"Feature","id":"37137","properties":{"name":"Pamlico"},"geometry":{"type":"Polygon","coordinates":[[[-76.624493,35.253119],[-76.602586,35.335273],[-76.646401,35.01761],[-76.712124,34.979272],[-76.89834,35.253119],[-76.624493,35.253119]]]}}, -{"type":"Feature","id":"37139","properties":{"name":"Pasquotank"},"geometry":{"type":"Polygon","coordinates":[[[-76.493047,36.512815],[-76.049415,36.184199],[-76.191815,36.118475],[-76.454708,36.375892],[-76.493047,36.512815]]]}}, -{"type":"Feature","id":"37141","properties":{"name":"Pender"},"geometry":{"type":"Polygon","coordinates":[[[-78.015636,34.732809],[-77.681543,34.721856],[-77.517235,34.442532],[-77.714404,34.294654],[-77.960867,34.376808],[-78.032067,34.332993],[-78.125175,34.365854],[-78.163514,34.354901],[-78.256622,34.398716],[-78.256622,34.55207],[-78.114221,34.721856],[-78.015636,34.732809]]]}}, -{"type":"Feature","id":"37143","properties":{"name":"Perquimans"},"geometry":{"type":"Polygon","coordinates":[[[-76.454708,36.375892],[-76.191815,36.118475],[-76.410893,36.07466],[-76.55877,36.353984],[-76.454708,36.375892]]]}}, -{"type":"Feature","id":"37145","properties":{"name":"Person"},"geometry":{"type":"Polygon","coordinates":[[[-79.138409,36.5402],[-78.798839,36.5402],[-78.804316,36.233491],[-78.952193,36.238968],[-79.15484,36.244445],[-79.138409,36.5402]]]}}, -{"type":"Feature","id":"37147","properties":{"name":"Pitt"},"geometry":{"type":"Polygon","coordinates":[[[-77.413173,35.822721],[-77.352926,35.817244],[-77.172187,35.73509],[-77.188618,35.417427],[-77.391265,35.34075],[-77.446034,35.379088],[-77.473419,35.428381],[-77.681543,35.636505],[-77.697974,35.652935],[-77.659635,35.674843],[-77.413173,35.822721]]]}}, -{"type":"Feature","id":"37149","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-82.09048,35.357181],[-81.969987,35.187396],[-82.216449,35.198349],[-82.353373,35.192872],[-82.260265,35.395519],[-82.09048,35.357181]]]}}, -{"type":"Feature","id":"37151","properties":{"name":"Randolph"},"geometry":{"type":"Polygon","coordinates":[[[-80.036627,35.921306],[-79.543702,35.899398],[-79.543702,35.844628],[-79.554656,35.516012],[-79.768257,35.510535],[-80.064012,35.505058],[-80.047581,35.921306],[-80.036627,35.921306]]]}}, -{"type":"Feature","id":"37153","properties":{"name":"Richmond"},"geometry":{"type":"Polygon","coordinates":[[[-79.729918,35.176442],[-79.614903,35.165488],[-79.461548,35.044995],[-79.686103,34.80401],[-79.927088,34.80401],[-80.074966,35.14358],[-79.729918,35.176442]]]}}, -{"type":"Feature","id":"37155","properties":{"name":"Robeson"},"geometry":{"type":"Polygon","coordinates":[[[-79.034347,34.951887],[-78.9029,34.836871],[-78.870039,34.48087],[-79.072686,34.300131],[-79.450595,34.623271],[-79.461548,34.628748],[-79.346533,34.836871],[-79.034347,34.951887]]]}}, -{"type":"Feature","id":"37157","properties":{"name":"Rockingham"},"geometry":{"type":"Polygon","coordinates":[[[-79.965427,36.5402],[-79.713488,36.5402],[-79.510841,36.5402],[-79.532749,36.249922],[-79.532749,36.238968],[-80.036627,36.255399],[-80.025673,36.5402],[-79.965427,36.5402]]]}}, -{"type":"Feature","id":"37159","properties":{"name":"Rowan"},"geometry":{"type":"Polygon","coordinates":[[[-80.688383,35.861059],[-80.458352,35.740566],[-80.184505,35.505058],[-80.233797,35.505058],[-80.294043,35.505058],[-80.737675,35.505058],[-80.710291,35.850105],[-80.688383,35.861059]]]}}, -{"type":"Feature","id":"37161","properties":{"name":"Rutherford"},"geometry":{"type":"Polygon","coordinates":[[[-81.82211,35.576258],[-81.690663,35.581735],[-81.76734,35.181919],[-81.876879,35.181919],[-81.969987,35.187396],[-82.09048,35.357181],[-82.260265,35.395519],[-82.265742,35.466719],[-82.167157,35.526966],[-81.82211,35.576258]]]}}, -{"type":"Feature","id":"37163","properties":{"name":"Sampson"},"geometry":{"type":"Polygon","coordinates":[[[-78.541422,35.313365],[-78.305914,35.28598],[-78.163514,35.187396],[-78.114221,34.721856],[-78.256622,34.55207],[-78.49213,34.847825],[-78.49213,34.858779],[-78.6181,35.247642],[-78.541422,35.313365]]]}}, -{"type":"Feature","id":"37165","properties":{"name":"Scotland"},"geometry":{"type":"Polygon","coordinates":[[[-79.461548,35.044995],[-79.346533,34.836871],[-79.461548,34.628748],[-79.686103,34.80401],[-79.461548,35.044995]]]}}, -{"type":"Feature","id":"37167","properties":{"name":"Stanly"},"geometry":{"type":"Polygon","coordinates":[[[-80.233797,35.505058],[-80.184505,35.505058],[-80.074966,35.14358],[-80.173551,35.149057],[-80.277612,35.198349],[-80.507644,35.187396],[-80.294043,35.505058],[-80.233797,35.505058]]]}}, -{"type":"Feature","id":"37169","properties":{"name":"Stokes"},"geometry":{"type":"Polygon","coordinates":[[[-80.441921,36.551154],[-80.053058,36.5402],[-80.025673,36.5402],[-80.036627,36.255399],[-80.036627,36.255399],[-80.452875,36.260876],[-80.441921,36.551154]]]}}, -{"type":"Feature","id":"37171","properties":{"name":"Surry"},"geometry":{"type":"Polygon","coordinates":[[[-80.83626,36.556631],[-80.611706,36.556631],[-80.441921,36.551154],[-80.452875,36.260876],[-80.452875,36.238968],[-80.874599,36.238968],[-80.967707,36.403276],[-80.901984,36.562108],[-80.83626,36.556631],[-80.83626,36.556631]]]}}, -{"type":"Feature","id":"37173","properties":{"name":"Swain"},"geometry":{"type":"Polygon","coordinates":[[[-83.662362,35.570781],[-83.257068,35.696751],[-83.185868,35.516012],[-83.207776,35.516012],[-83.339222,35.329796],[-83.678792,35.280503],[-83.952639,35.461243],[-83.662362,35.570781]]]}}, -{"type":"Feature","id":"37175","properties":{"name":"Transylvania"},"geometry":{"type":"Polygon","coordinates":[[[-82.747713,35.422904],[-82.572451,35.14358],[-82.764143,35.066903],[-82.89559,35.055949],[-83.010606,35.028564],[-82.922975,35.291457],[-82.747713,35.422904]]]}}, -{"type":"Feature","id":"37177","properties":{"name":"Tyrrell"},"geometry":{"type":"Polygon","coordinates":[[[-76.000122,35.904875],[-76.027507,35.669366],[-76.394462,35.696751],[-76.367077,35.943213],[-76.000122,35.904875]]]}}, -{"type":"Feature","id":"37179","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-80.55146,35.209303],[-80.507644,35.187396],[-80.277612,35.198349],[-80.321428,34.814964],[-80.562413,34.814964],[-80.841737,35.00118],[-80.55146,35.209303]]]}}, -{"type":"Feature","id":"37181","properties":{"name":"Vance"},"geometry":{"type":"Polygon","coordinates":[[[-78.322345,36.545677],[-78.305914,36.266353],[-78.497607,36.173245],[-78.459268,36.5402],[-78.322345,36.545677]]]}}, -{"type":"Feature","id":"37183","properties":{"name":"Wake"},"geometry":{"type":"Polygon","coordinates":[[[-78.749546,36.069183],[-78.546899,36.01989],[-78.256622,35.817244],[-78.711208,35.521489],[-78.913854,35.581735],[-78.908377,35.866536],[-78.749546,36.069183]]]}}, -{"type":"Feature","id":"37185","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-78.322345,36.545677],[-78.048498,36.545677],[-77.90062,36.545677],[-77.90062,36.507338],[-78.004682,36.200629],[-78.163514,36.249922],[-78.305914,36.266353],[-78.322345,36.545677]]]}}, -{"type":"Feature","id":"37187","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-76.367077,35.943213],[-76.394462,35.696751],[-76.635447,35.707705],[-76.640924,35.707705],[-76.843571,35.707705],[-76.761417,35.866536],[-76.690217,35.943213],[-76.367077,35.943213]]]}}, -{"type":"Feature","id":"37189","properties":{"name":"Watauga"},"geometry":{"type":"Polygon","coordinates":[[[-81.734479,36.392322],[-81.477062,36.238968],[-81.542786,36.118475],[-81.685186,36.123952],[-81.811156,36.112998],[-81.920695,36.288261],[-81.734479,36.392322]]]}}, -{"type":"Feature","id":"37191","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-78.064929,35.587212],[-77.823943,35.570781],[-77.807512,35.368135],[-77.834897,35.176442],[-78.043021,35.192872],[-78.163514,35.187396],[-78.305914,35.28598],[-78.064929,35.587212]]]}}, -{"type":"Feature","id":"37193","properties":{"name":"Wilkes"},"geometry":{"type":"Polygon","coordinates":[[[-81.082723,36.430661],[-80.967707,36.403276],[-80.874599,36.238968],[-80.880076,36.058229],[-81.027953,36.047275],[-81.329185,35.997983],[-81.542786,36.118475],[-81.477062,36.238968],[-81.252508,36.364938],[-81.082723,36.430661]]]}}, -{"type":"Feature","id":"37195","properties":{"name":"Wilson"},"geometry":{"type":"Polygon","coordinates":[[[-77.82942,35.866536],[-77.659635,35.674843],[-77.697974,35.652935],[-77.823943,35.570781],[-78.064929,35.587212],[-78.190898,35.729613],[-77.82942,35.866536],[-77.82942,35.866536]]]}}, -{"type":"Feature","id":"37197","properties":{"name":"Yadkin"},"geometry":{"type":"Polygon","coordinates":[[[-80.452875,36.238968],[-80.49669,36.047275],[-80.69386,36.052752],[-80.880076,36.058229],[-80.874599,36.238968],[-80.452875,36.238968]]]}}, -{"type":"Feature","id":"37199","properties":{"name":"Yancey"},"geometry":{"type":"Polygon","coordinates":[[[-82.419096,36.07466],[-82.134295,35.822721],[-82.276696,35.702228],[-82.408142,35.817244],[-82.506727,35.976075],[-82.419096,36.07466]]]}}, -{"type":"Feature","id":"38001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-102.49756,46.283677],[-101.999158,46.207],[-101.999158,46.053645],[-101.999158,45.944106],[-101.999158,45.944106],[-102.623529,45.944106],[-102.941192,45.944106],[-102.995961,45.944106],[-102.995961,46.2782],[-102.924761,46.283677],[-102.49756,46.283677]]]}}, -{"type":"Feature","id":"38003","properties":{"name":"Barnes"},"geometry":{"type":"Polygon","coordinates":[[[-98.088623,47.242141],[-97.962653,47.242141],[-97.705237,47.242141],[-97.683329,46.628724],[-97.957176,46.628724],[-98.033853,46.628724],[-98.439147,46.628724],[-98.466531,47.242141],[-98.088623,47.242141]]]}}, -{"type":"Feature","id":"38005","properties":{"name":"Benson"},"geometry":{"type":"Polygon","coordinates":[[[-99.819336,48.370391],[-99.490719,48.370391],[-99.200441,48.370391],[-98.992318,47.992482],[-98.526778,47.915805],[-98.526778,47.844605],[-98.636317,47.850082],[-99.299026,47.844605],[-99.813859,47.850082],[-99.819336,48.370391]]]}}, -{"type":"Feature","id":"38007","properties":{"name":"Billings"},"geometry":{"type":"Polygon","coordinates":[[[-103.664148,47.329772],[-103.100023,47.329772],[-103.0343,46.979248],[-103.23147,46.628724],[-103.609378,46.628724],[-103.664148,47.329772]]]}}, -{"type":"Feature","id":"38009","properties":{"name":"Bottineau"},"geometry":{"type":"Polygon","coordinates":[[[-100.180814,49.000239],[-100.147952,48.545653],[-100.279399,48.545653],[-100.668261,48.633284],[-101.057124,48.545653],[-101.451464,48.545653],[-101.495279,49.000239],[-100.180814,49.000239]]]}}, -{"type":"Feature","id":"38011","properties":{"name":"Bowman"},"geometry":{"type":"Polygon","coordinates":[[[-102.995961,46.2782],[-102.995961,45.944106],[-104.047534,45.944106],[-104.047534,46.2782],[-102.995961,46.2782]]]}}, -{"type":"Feature","id":"38013","properties":{"name":"Burke"},"geometry":{"type":"Polygon","coordinates":[[[-102.021066,49.000239],[-102.021066,48.808546],[-102.152512,48.808546],[-102.234666,48.545653],[-102.886422,48.545653],[-102.886422,48.633284],[-102.941192,49.000239],[-102.021066,49.000239]]]}}, -{"type":"Feature","id":"38015","properties":{"name":"Burleigh"},"geometry":{"type":"Polygon","coordinates":[[[-100.608015,47.329772],[-100.115091,47.329772],[-100.082229,46.634201],[-100.586107,46.634201],[-100.662785,46.634201],[-100.936632,46.984725],[-100.964016,47.15451],[-100.673738,47.329772],[-100.608015,47.329772]]]}}, -{"type":"Feature","id":"38017","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-97.453297,47.236664],[-96.834403,47.236664],[-96.828926,47.149033],[-96.790588,46.628724],[-97.278035,46.628724],[-97.683329,46.628724],[-97.705237,47.242141],[-97.453297,47.236664]]]}}, -{"type":"Feature","id":"38019","properties":{"name":"Cavalier"},"geometry":{"type":"Polygon","coordinates":[[[-97.951699,49.000239],[-97.929791,48.545653],[-98.017422,48.545653],[-98.318654,48.545653],[-98.838963,48.545653],[-98.97041,48.545653],[-98.997795,49.000239],[-97.951699,49.000239]]]}}, -{"type":"Feature","id":"38021","properties":{"name":"Dickey"},"geometry":{"type":"Polygon","coordinates":[[[-98.335085,46.283677],[-98.033853,46.283677],[-98.006468,46.283677],[-98.006468,45.938629],[-98.723948,45.938629],[-99.003272,45.938629],[-99.003272,46.283677],[-98.335085,46.283677]]]}}, -{"type":"Feature","id":"38023","properties":{"name":"Divide"},"geometry":{"type":"Polygon","coordinates":[[[-102.941192,49.000239],[-102.886422,48.633284],[-104.047534,48.633284],[-104.047534,49.000239],[-102.941192,49.000239]]]}}, -{"type":"Feature","id":"38025","properties":{"name":"Dunn"},"geometry":{"type":"Polygon","coordinates":[[[-102.63996,47.822697],[-102.388021,47.756974],[-102.207282,47.576235],[-102.147035,47.01211],[-103.0343,46.979248],[-103.100023,47.329772],[-103.100023,47.67482],[-102.63996,47.822697]]]}}, -{"type":"Feature","id":"38027","properties":{"name":"Eddy"},"geometry":{"type":"Polygon","coordinates":[[[-98.636317,47.850082],[-98.526778,47.844605],[-98.499393,47.67482],[-98.499393,47.587189],[-99.200441,47.587189],[-99.266165,47.587189],[-99.299026,47.844605],[-98.636317,47.850082]]]}}, -{"type":"Feature","id":"38029","properties":{"name":"Emmons"},"geometry":{"type":"Polygon","coordinates":[[[-100.586107,46.634201],[-100.082229,46.634201],[-99.917921,46.634201],[-99.879582,46.283677],[-99.879582,45.944106],[-100.432753,45.944106],[-100.498476,45.944106],[-100.50943,45.944106],[-100.591584,46.426077],[-100.662785,46.634201],[-100.586107,46.634201]]]}}, -{"type":"Feature","id":"38031","properties":{"name":"Foster"},"geometry":{"type":"Polygon","coordinates":[[[-99.200441,47.587189],[-98.499393,47.587189],[-98.499393,47.324295],[-99.266165,47.329772],[-99.266165,47.587189],[-99.200441,47.587189]]]}}, -{"type":"Feature","id":"38033","properties":{"name":"Golden Valley"},"geometry":{"type":"Polygon","coordinates":[[[-103.992764,47.329772],[-103.664148,47.329772],[-103.609378,46.628724],[-104.047534,46.541093],[-104.047534,46.639678],[-104.047534,47.329772],[-103.992764,47.329772]]]}}, -{"type":"Feature","id":"38035","properties":{"name":"Grand Forks"},"geometry":{"type":"Polygon","coordinates":[[[-97.825729,48.195129],[-97.141112,48.195129],[-97.146589,48.173221],[-96.889173,47.67482],[-97.475205,47.669343],[-97.880499,47.67482],[-97.902407,48.195129],[-97.825729,48.195129]]]}}, -{"type":"Feature","id":"38037","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-102.097743,46.716355],[-101.29811,46.628724],[-101.024263,46.283677],[-101.999158,46.053645],[-101.999158,46.207],[-102.097743,46.628724],[-102.097743,46.716355]]]}}, -{"type":"Feature","id":"38039","properties":{"name":"Griggs"},"geometry":{"type":"Polygon","coordinates":[[[-98.11053,47.67482],[-97.984561,47.67482],[-97.962653,47.242141],[-98.088623,47.242141],[-98.466531,47.242141],[-98.499393,47.324295],[-98.499393,47.587189],[-98.499393,47.67482],[-98.11053,47.67482]]]}}, -{"type":"Feature","id":"38041","properties":{"name":"Hettinger"},"geometry":{"type":"Polygon","coordinates":[[[-102.17442,46.628724],[-102.097743,46.628724],[-101.999158,46.207],[-102.49756,46.283677],[-102.924761,46.283677],[-102.930238,46.628724],[-102.17442,46.628724]]]}}, -{"type":"Feature","id":"38043","properties":{"name":"Kidder"},"geometry":{"type":"Polygon","coordinates":[[[-99.863151,47.329772],[-99.479765,47.329772],[-99.452381,46.634201],[-99.917921,46.634201],[-100.082229,46.634201],[-100.115091,47.329772],[-100.032936,47.329772],[-99.863151,47.329772]]]}}, -{"type":"Feature","id":"38045","properties":{"name":"LaMoure"},"geometry":{"type":"Polygon","coordinates":[[[-98.033853,46.628724],[-98.033853,46.283677],[-98.335085,46.283677],[-99.003272,46.283677],[-99.036133,46.283677],[-99.036133,46.628724],[-98.439147,46.628724],[-98.033853,46.628724]]]}}, -{"type":"Feature","id":"38047","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-99.917921,46.634201],[-99.452381,46.634201],[-99.036133,46.628724],[-99.036133,46.283677],[-99.348319,46.283677],[-99.879582,46.283677],[-99.917921,46.634201]]]}}, -{"type":"Feature","id":"38049","properties":{"name":"McHenry"},"geometry":{"type":"Polygon","coordinates":[[[-100.668261,48.633284],[-100.279399,48.545653],[-100.197245,47.850082],[-100.520384,47.850082],[-100.586107,47.850082],[-100.969493,47.850082],[-101.062601,48.458022],[-101.057124,48.545653],[-100.668261,48.633284]]]}}, -{"type":"Feature","id":"38051","properties":{"name":"McIntosh"},"geometry":{"type":"Polygon","coordinates":[[[-99.348319,46.283677],[-99.036133,46.283677],[-99.003272,46.283677],[-99.003272,45.938629],[-99.720751,45.938629],[-99.879582,45.944106],[-99.879582,46.283677],[-99.348319,46.283677]]]}}, -{"type":"Feature","id":"38053","properties":{"name":"McKenzie"},"geometry":{"type":"Polygon","coordinates":[[[-103.171223,48.134883],[-102.826176,48.123929],[-102.63996,47.822697],[-103.100023,47.67482],[-103.100023,47.329772],[-103.664148,47.329772],[-103.992764,47.329772],[-104.047534,47.329772],[-104.047534,47.395496],[-104.042057,47.997959],[-103.171223,48.134883]]]}}, -{"type":"Feature","id":"38055","properties":{"name":"McLean"},"geometry":{"type":"Polygon","coordinates":[[[-100.969493,47.850082],[-100.586107,47.850082],[-100.673738,47.329772],[-100.964016,47.15451],[-101.254294,47.264049],[-101.429556,47.559804],[-102.081312,47.576235],[-102.207282,47.576235],[-102.388021,47.756974],[-101.873188,47.850082],[-100.969493,47.850082]]]}}, -{"type":"Feature","id":"38057","properties":{"name":"Mercer"},"geometry":{"type":"Polygon","coordinates":[[[-102.081312,47.576235],[-101.429556,47.559804],[-101.254294,47.264049],[-101.76365,46.979248],[-102.097743,46.979248],[-102.147035,47.01211],[-102.207282,47.576235],[-102.081312,47.576235]]]}}, -{"type":"Feature","id":"38059","properties":{"name":"Morton"},"geometry":{"type":"Polygon","coordinates":[[[-100.936632,46.984725],[-100.662785,46.634201],[-100.591584,46.426077],[-101.024263,46.283677],[-101.29811,46.628724],[-102.097743,46.716355],[-102.097743,46.979248],[-101.76365,46.979248],[-100.936632,46.984725]]]}}, -{"type":"Feature","id":"38061","properties":{"name":"Mountrail"},"geometry":{"type":"Polygon","coordinates":[[[-102.886422,48.545653],[-102.234666,48.545653],[-101.971773,48.545653],[-101.873188,47.850082],[-102.388021,47.756974],[-102.63996,47.822697],[-102.826176,48.123929],[-102.886422,48.545653]]]}}, -{"type":"Feature","id":"38063","properties":{"name":"Nelson"},"geometry":{"type":"Polygon","coordinates":[[[-97.91336,48.195129],[-97.902407,48.195129],[-97.880499,47.67482],[-97.979084,47.67482],[-97.984561,47.67482],[-98.11053,47.67482],[-98.499393,47.67482],[-98.526778,47.844605],[-98.526778,47.915805],[-98.291269,48.195129],[-97.91336,48.195129]]]}}, -{"type":"Feature","id":"38065","properties":{"name":"Oliver"},"geometry":{"type":"Polygon","coordinates":[[[-101.254294,47.264049],[-100.964016,47.15451],[-100.936632,46.984725],[-101.76365,46.979248],[-101.254294,47.264049]]]}}, -{"type":"Feature","id":"38067","properties":{"name":"Pembina"},"geometry":{"type":"Polygon","coordinates":[[[-97.228743,49.000239],[-97.16302,48.545653],[-97.16302,48.540176],[-97.929791,48.545653],[-97.951699,49.000239],[-97.228743,49.000239]]]}}, -{"type":"Feature","id":"38069","properties":{"name":"Pierce"},"geometry":{"type":"Polygon","coordinates":[[[-99.616689,48.545653],[-99.490719,48.545653],[-99.490719,48.370391],[-99.819336,48.370391],[-99.813859,47.850082],[-100.000075,47.850082],[-100.071275,47.844605],[-100.197245,47.850082],[-100.279399,48.545653],[-100.147952,48.545653],[-99.616689,48.545653]]]}}, -{"type":"Feature","id":"38071","properties":{"name":"Ramsey"},"geometry":{"type":"Polygon","coordinates":[[[-98.838963,48.545653],[-98.318654,48.545653],[-98.291269,48.195129],[-98.526778,47.915805],[-98.992318,47.992482],[-99.200441,48.370391],[-98.97041,48.545653],[-98.838963,48.545653]]]}}, -{"type":"Feature","id":"38073","properties":{"name":"Ransom"},"geometry":{"type":"Polygon","coordinates":[[[-97.957176,46.628724],[-97.683329,46.628724],[-97.278035,46.628724],[-97.278035,46.283677],[-98.006468,46.283677],[-98.033853,46.283677],[-98.033853,46.628724],[-97.957176,46.628724]]]}}, -{"type":"Feature","id":"38075","properties":{"name":"Renville"},"geometry":{"type":"Polygon","coordinates":[[[-101.495279,49.000239],[-101.451464,48.545653],[-101.057124,48.545653],[-101.062601,48.458022],[-101.840327,48.458022],[-102.021066,48.808546],[-102.021066,49.000239],[-101.495279,49.000239]]]}}, -{"type":"Feature","id":"38077","properties":{"name":"Richland"},"geometry":{"type":"Polygon","coordinates":[[[-96.790588,46.628724],[-96.790588,46.628724],[-96.576987,46.020784],[-96.560556,45.933153],[-96.735818,45.933153],[-97.228743,45.933153],[-97.278035,46.283677],[-97.278035,46.628724],[-96.790588,46.628724]]]}}, -{"type":"Feature","id":"38079","properties":{"name":"Rolette"},"geometry":{"type":"Polygon","coordinates":[[[-99.523581,49.000239],[-99.490719,48.545653],[-99.616689,48.545653],[-100.147952,48.545653],[-100.180814,49.000239],[-99.523581,49.000239]]]}}, -{"type":"Feature","id":"38081","properties":{"name":"Sargent"},"geometry":{"type":"Polygon","coordinates":[[[-98.006468,46.283677],[-97.278035,46.283677],[-97.228743,45.933153],[-97.853114,45.933153],[-97.979084,45.938629],[-98.006468,45.938629],[-98.006468,46.283677]]]}}, -{"type":"Feature","id":"38083","properties":{"name":"Sheridan"},"geometry":{"type":"Polygon","coordinates":[[[-100.520384,47.850082],[-100.197245,47.850082],[-100.071275,47.844605],[-100.032936,47.329772],[-100.115091,47.329772],[-100.608015,47.329772],[-100.673738,47.329772],[-100.586107,47.850082],[-100.520384,47.850082]]]}}, -{"type":"Feature","id":"38085","properties":{"name":"Sioux"},"geometry":{"type":"Polygon","coordinates":[[[-100.591584,46.426077],[-100.50943,45.944106],[-101.999158,45.944106],[-101.999158,46.053645],[-101.024263,46.283677],[-100.591584,46.426077]]]}}, -{"type":"Feature","id":"38087","properties":{"name":"Slope"},"geometry":{"type":"Polygon","coordinates":[[[-103.23147,46.628724],[-102.930238,46.628724],[-102.924761,46.283677],[-102.995961,46.2782],[-104.047534,46.2782],[-104.047534,46.541093],[-103.609378,46.628724],[-103.23147,46.628724]]]}}, -{"type":"Feature","id":"38089","properties":{"name":"Stark"},"geometry":{"type":"Polygon","coordinates":[[[-102.147035,47.01211],[-102.097743,46.979248],[-102.097743,46.716355],[-102.097743,46.628724],[-102.17442,46.628724],[-102.930238,46.628724],[-103.23147,46.628724],[-103.0343,46.979248],[-102.147035,47.01211]]]}}, -{"type":"Feature","id":"38091","properties":{"name":"Steele"},"geometry":{"type":"Polygon","coordinates":[[[-97.979084,47.67482],[-97.880499,47.67482],[-97.475205,47.669343],[-97.453297,47.236664],[-97.705237,47.242141],[-97.962653,47.242141],[-97.984561,47.67482],[-97.979084,47.67482]]]}}, -{"type":"Feature","id":"38093","properties":{"name":"Stutsman"},"geometry":{"type":"Polygon","coordinates":[[[-99.479765,47.329772],[-99.266165,47.329772],[-98.499393,47.324295],[-98.466531,47.242141],[-98.439147,46.628724],[-99.036133,46.628724],[-99.452381,46.634201],[-99.479765,47.329772]]]}}, -{"type":"Feature","id":"38095","properties":{"name":"Towner"},"geometry":{"type":"Polygon","coordinates":[[[-98.997795,49.000239],[-98.97041,48.545653],[-99.200441,48.370391],[-99.490719,48.370391],[-99.490719,48.545653],[-99.523581,49.000239],[-98.997795,49.000239]]]}}, -{"type":"Feature","id":"38097","properties":{"name":"Traill"},"geometry":{"type":"Polygon","coordinates":[[[-97.475205,47.669343],[-96.889173,47.67482],[-96.850834,47.499557],[-96.834403,47.236664],[-97.453297,47.236664],[-97.475205,47.669343]]]}}, -{"type":"Feature","id":"38099","properties":{"name":"Walsh"},"geometry":{"type":"Polygon","coordinates":[[[-98.017422,48.545653],[-97.929791,48.545653],[-97.16302,48.540176],[-97.141112,48.195129],[-97.825729,48.195129],[-97.902407,48.195129],[-97.91336,48.195129],[-98.291269,48.195129],[-98.318654,48.545653],[-98.017422,48.545653]]]}}, -{"type":"Feature","id":"38101","properties":{"name":"Ward"},"geometry":{"type":"Polygon","coordinates":[[[-102.152512,48.808546],[-102.021066,48.808546],[-101.840327,48.458022],[-101.062601,48.458022],[-100.969493,47.850082],[-101.873188,47.850082],[-101.971773,48.545653],[-102.234666,48.545653],[-102.152512,48.808546]]]}}, -{"type":"Feature","id":"38103","properties":{"name":"Wells"},"geometry":{"type":"Polygon","coordinates":[[[-100.000075,47.850082],[-99.813859,47.850082],[-99.299026,47.844605],[-99.266165,47.587189],[-99.266165,47.329772],[-99.479765,47.329772],[-99.863151,47.329772],[-100.032936,47.329772],[-100.071275,47.844605],[-100.000075,47.850082]]]}}, -{"type":"Feature","id":"38105","properties":{"name":"Williams"},"geometry":{"type":"Polygon","coordinates":[[[-104.047534,48.633284],[-102.886422,48.633284],[-102.886422,48.545653],[-102.826176,48.123929],[-103.171223,48.134883],[-104.042057,47.997959],[-104.047534,48.386822],[-104.047534,48.633284]]]}}, -{"type":"Feature","id":"39001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-83.383038,39.054115],[-83.273499,39.015777],[-83.273499,39.0103],[-83.268022,38.61596],[-83.645931,38.637868],[-83.706177,38.637868],[-83.673316,39.021254],[-83.383038,39.054115]]]}}, -{"type":"Feature","id":"39003","properties":{"name":"Allen"},"geometry":{"type":"Polygon","coordinates":[[[-83.881439,40.921752],[-83.881439,40.81769],[-83.881439,40.642428],[-84.253871,40.686244],[-84.396272,40.686244],[-84.341502,40.861506],[-83.881439,40.921752]]]}}, -{"type":"Feature","id":"39005","properties":{"name":"Ashland"},"geometry":{"type":"Polygon","coordinates":[[[-82.375281,41.064153],[-82.336942,41.064153],[-82.172634,41.064153],[-82.128818,40.992952],[-82.128818,40.669813],[-82.221926,40.565751],[-82.336942,40.554797],[-82.435527,40.992952],[-82.375281,41.064153]]]}}, -{"type":"Feature","id":"39007","properties":{"name":"Ashtabula"},"geometry":{"type":"Polygon","coordinates":[[[-80.518598,41.978802],[-80.518598,41.847355],[-80.518598,41.502308],[-81.000569,41.502308],[-81.006046,41.715908],[-81.000569,41.852832],[-80.518598,41.978802],[-80.518598,41.978802]]]}}, -{"type":"Feature","id":"39009","properties":{"name":"Athens"},"geometry":{"type":"Polygon","coordinates":[[[-82.046664,39.552517],[-81.844017,39.448455],[-81.723525,39.218424],[-81.756386,39.180085],[-82.271219,39.201993],[-82.28765,39.382732],[-82.16168,39.557994],[-82.046664,39.552517]]]}}, -{"type":"Feature","id":"39011","properties":{"name":"Auglaize"},"geometry":{"type":"Polygon","coordinates":[[[-84.253871,40.686244],[-83.881439,40.642428],[-83.881439,40.538366],[-84.001932,40.483597],[-84.105994,40.483597],[-84.43461,40.35215],[-84.456518,40.686244],[-84.396272,40.686244],[-84.253871,40.686244]]]}}, -{"type":"Feature","id":"39013","properties":{"name":"Belmont"},"geometry":{"type":"Polygon","coordinates":[[[-81.219646,40.171411],[-80.885553,40.160457],[-80.704814,40.15498],[-80.732199,40.034488],[-80.81983,39.848272],[-81.236077,39.87018],[-81.236077,39.952334],[-81.225123,40.171411],[-81.219646,40.171411]]]}}, -{"type":"Feature","id":"39015","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-83.990978,39.256762],[-83.865008,39.245808],[-83.673316,39.021254],[-83.706177,38.637868],[-83.848578,38.747407],[-83.903347,38.769315],[-84.051224,38.769315],[-83.990978,39.256762]]]}}, -{"type":"Feature","id":"39017","properties":{"name":"Butler"},"geometry":{"type":"Polygon","coordinates":[[[-84.478426,39.590856],[-84.36341,39.590856],[-84.352456,39.289624],[-84.598918,39.306055],[-84.817996,39.306055],[-84.817996,39.519655],[-84.812519,39.568948],[-84.478426,39.590856]]]}}, -{"type":"Feature","id":"39019","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-81.121061,40.730059],[-81.0882,40.730059],[-80.863645,40.598613],[-80.940322,40.423351],[-81.186785,40.434304],[-81.268939,40.434304],[-81.318231,40.653382],[-81.121061,40.730059]]]}}, -{"type":"Feature","id":"39021","properties":{"name":"Champaign"},"geometry":{"type":"Polygon","coordinates":[[[-83.881439,40.264519],[-83.552823,40.231658],[-83.50353,40.111165],[-83.514484,40.01258],[-84.034794,40.039965],[-84.02384,40.182365],[-84.012886,40.275473],[-83.881439,40.264519]]]}}, -{"type":"Feature","id":"39023","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-84.034794,40.039965],[-83.514484,40.01258],[-83.645931,39.771595],[-84.029317,39.848272],[-84.051224,39.848272],[-84.051224,39.881133],[-84.034794,40.039965]]]}}, -{"type":"Feature","id":"39025","properties":{"name":"Clermont"},"geometry":{"type":"Polygon","coordinates":[[[-84.259348,39.273193],[-84.007409,39.256762],[-83.990978,39.256762],[-84.051224,38.769315],[-84.231963,38.829561],[-84.231963,38.873376],[-84.319594,39.021254],[-84.259348,39.273193]]]}}, -{"type":"Feature","id":"39027","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-83.974547,39.568948],[-83.667839,39.552517],[-83.591161,39.377255],[-83.865008,39.245808],[-83.990978,39.256762],[-84.007409,39.256762],[-83.974547,39.568948],[-83.974547,39.568948]]]}}, -{"type":"Feature","id":"39029","properties":{"name":"Columbiana"},"geometry":{"type":"Polygon","coordinates":[[[-80.858168,40.927229],[-80.518598,40.899844],[-80.518598,40.850552],[-80.518598,40.636951],[-80.666475,40.582182],[-80.863645,40.598613],[-81.0882,40.730059],[-81.0882,40.905321],[-80.858168,40.927229]]]}}, -{"type":"Feature","id":"39031","properties":{"name":"Coshocton"},"geometry":{"type":"Polygon","coordinates":[[[-82.183588,40.456212],[-81.707094,40.445258],[-81.62494,40.220704],[-81.652325,40.220704],[-81.718048,40.149503],[-82.189065,40.165934],[-82.194542,40.237135],[-82.183588,40.456212]]]}}, -{"type":"Feature","id":"39033","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-82.725805,40.998429],[-82.725805,40.713628],[-82.857251,40.713628],[-82.857251,40.702674],[-82.977744,40.702674],[-83.109191,40.702674],[-83.114668,40.992952],[-82.829867,40.998429],[-82.725805,40.998429]]]}}, -{"type":"Feature","id":"39035","properties":{"name":"Cuyahoga"},"geometry":{"type":"Polygon","coordinates":[[[-81.488016,41.633754],[-81.389431,41.568031],[-81.389431,41.348953],[-81.389431,41.348953],[-81.537309,41.348953],[-81.685186,41.277753],[-81.876879,41.277753],[-81.969987,41.507785],[-81.488016,41.633754]]]}}, -{"type":"Feature","id":"39037","properties":{"name":"Darke"},"geometry":{"type":"Polygon","coordinates":[[[-84.456518,40.35215],[-84.43461,40.35215],[-84.43461,40.198796],[-84.423656,39.919472],[-84.483903,39.919472],[-84.812519,39.919472],[-84.812519,40.007103],[-84.801565,40.308335],[-84.801565,40.35215],[-84.456518,40.35215]]]}}, -{"type":"Feature","id":"39039","properties":{"name":"Defiance"},"geometry":{"type":"Polygon","coordinates":[[[-84.270302,41.425631],[-84.226487,41.168214],[-84.341502,41.162737],[-84.577011,41.250368],[-84.801565,41.250368],[-84.801565,41.272276],[-84.801565,41.425631],[-84.341502,41.425631],[-84.270302,41.425631]]]}}, -{"type":"Feature","id":"39041","properties":{"name":"Delaware"},"geometry":{"type":"Polygon","coordinates":[[[-83.246114,40.445258],[-83.02156,40.434304],[-82.742236,40.346673],[-82.75319,40.275473],[-82.764143,40.127596],[-83.03799,40.13855],[-83.169437,40.144027],[-83.246114,40.445258]]]}}, -{"type":"Feature","id":"39043","properties":{"name":"Erie"},"geometry":{"type":"Polygon","coordinates":[[[-82.775097,41.4804],[-82.692943,41.491354],[-82.347896,41.431108],[-82.342419,41.28323],[-82.840821,41.288707],[-82.955836,41.458492],[-82.775097,41.4804]]]}}, -{"type":"Feature","id":"39045","properties":{"name":"Fairfield"},"geometry":{"type":"Polygon","coordinates":[[[-82.797005,39.94138],[-82.780574,39.94138],[-82.462912,39.930426],[-82.375281,39.656579],[-82.731282,39.552517],[-82.82439,39.793502],[-82.797005,39.94138]]]}}, -{"type":"Feature","id":"39047","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-83.651408,39.716825],[-83.251591,39.694917],[-83.268022,39.514178],[-83.372084,39.377255],[-83.591161,39.377255],[-83.667839,39.552517],[-83.651408,39.716825]]]}}, -{"type":"Feature","id":"39049","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-83.03799,40.13855],[-82.764143,40.127596],[-82.780574,39.94138],[-82.797005,39.94138],[-82.82439,39.793502],[-83.246114,39.81541],[-83.207776,40.105688],[-83.169437,40.144027],[-83.03799,40.13855]]]}}, -{"type":"Feature","id":"39051","properties":{"name":"Fulton"},"geometry":{"type":"Polygon","coordinates":[[[-83.89787,41.721385],[-83.881439,41.721385],[-83.881439,41.485877],[-83.886916,41.485877],[-84.341502,41.485877],[-84.401749,41.704955],[-84.357933,41.704955],[-83.89787,41.721385]]]}}, -{"type":"Feature","id":"39053","properties":{"name":"Gallia"},"geometry":{"type":"Polygon","coordinates":[[[-82.435527,39.037685],[-82.320511,39.026731],[-82.101434,38.95553],[-82.216449,38.594052],[-82.265742,38.599529],[-82.28765,38.583099],[-82.577927,38.845992],[-82.435527,39.037685]]]}}, -{"type":"Feature","id":"39055","properties":{"name":"Geauga"},"geometry":{"type":"Polygon","coordinates":[[[-81.006046,41.715908],[-81.000569,41.502308],[-81.000569,41.348953],[-81.389431,41.348953],[-81.389431,41.568031],[-81.006046,41.715908]]]}}, -{"type":"Feature","id":"39057","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-84.029317,39.848272],[-83.645931,39.771595],[-83.651408,39.716825],[-83.667839,39.552517],[-83.974547,39.568948],[-83.974547,39.568948],[-84.111471,39.579902],[-84.051224,39.848272],[-84.029317,39.848272]]]}}, -{"type":"Feature","id":"39059","properties":{"name":"Guernsey"},"geometry":{"type":"Polygon","coordinates":[[[-81.652325,40.220704],[-81.62494,40.220704],[-81.340139,40.215227],[-81.225123,40.171411],[-81.236077,39.952334],[-81.471585,39.892087],[-81.69614,39.842795],[-81.718048,40.149503],[-81.652325,40.220704]]]}}, -{"type":"Feature","id":"39061","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-84.598918,39.306055],[-84.352456,39.289624],[-84.259348,39.273193],[-84.319594,39.021254],[-84.50581,39.092454],[-84.620826,39.076023],[-84.817996,39.103408],[-84.817996,39.306055],[-84.598918,39.306055]]]}}, -{"type":"Feature","id":"39063","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-83.881439,41.168214],[-83.421376,41.168214],[-83.421376,40.992952],[-83.514484,40.81769],[-83.574731,40.81769],[-83.881439,40.81769],[-83.881439,40.921752],[-83.881439,41.168214]]]}}, -{"type":"Feature","id":"39065","properties":{"name":"Hardin"},"geometry":{"type":"Polygon","coordinates":[[[-83.574731,40.81769],[-83.514484,40.81769],[-83.421376,40.686244],[-83.415899,40.505505],[-83.519961,40.505505],[-83.881439,40.538366],[-83.881439,40.642428],[-83.881439,40.81769],[-83.574731,40.81769]]]}}, -{"type":"Feature","id":"39067","properties":{"name":"Harrison"},"geometry":{"type":"Polygon","coordinates":[[[-81.186785,40.434304],[-80.940322,40.423351],[-80.885553,40.160457],[-81.219646,40.171411],[-81.225123,40.171411],[-81.340139,40.215227],[-81.268939,40.434304],[-81.186785,40.434304]]]}}, -{"type":"Feature","id":"39069","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-83.886916,41.485877],[-83.881439,41.485877],[-83.881439,41.414677],[-83.881439,41.168214],[-84.029317,41.168214],[-84.226487,41.168214],[-84.270302,41.425631],[-84.341502,41.425631],[-84.341502,41.485877],[-83.886916,41.485877]]]}}, -{"type":"Feature","id":"39071","properties":{"name":"Highland"},"geometry":{"type":"Polygon","coordinates":[[[-83.591161,39.377255],[-83.372084,39.377255],[-83.355653,39.196516],[-83.383038,39.054115],[-83.673316,39.021254],[-83.865008,39.245808],[-83.591161,39.377255]]]}}, -{"type":"Feature","id":"39073","properties":{"name":"Hocking"},"geometry":{"type":"Polygon","coordinates":[[[-82.375281,39.656579],[-82.16168,39.557994],[-82.28765,39.382732],[-82.747713,39.366301],[-82.742236,39.470363],[-82.731282,39.552517],[-82.375281,39.656579]]]}}, -{"type":"Feature","id":"39075","properties":{"name":"Holmes"},"geometry":{"type":"Polygon","coordinates":[[[-81.657801,40.669813],[-81.652325,40.669813],[-81.652325,40.636951],[-81.707094,40.445258],[-82.183588,40.456212],[-82.221926,40.565751],[-82.128818,40.669813],[-81.657801,40.669813]]]}}, -{"type":"Feature","id":"39077","properties":{"name":"Huron"},"geometry":{"type":"Polygon","coordinates":[[[-82.840821,41.288707],[-82.342419,41.28323],[-82.336942,41.064153],[-82.375281,41.064153],[-82.435527,40.992952],[-82.687466,40.992952],[-82.725805,40.998429],[-82.829867,40.998429],[-82.840821,41.255845],[-82.840821,41.288707]]]}}, -{"type":"Feature","id":"39079","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-82.671035,39.201993],[-82.435527,39.037685],[-82.577927,38.845992],[-82.649128,38.851469],[-82.807959,38.950054],[-82.786051,39.169131],[-82.764143,39.20747],[-82.671035,39.201993]]]}}, -{"type":"Feature","id":"39081","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-80.863645,40.598613],[-80.666475,40.582182],[-80.633614,40.395966],[-80.682906,40.187842],[-80.704814,40.15498],[-80.885553,40.160457],[-80.940322,40.423351],[-80.863645,40.598613]]]}}, -{"type":"Feature","id":"39083","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-82.221926,40.565751],[-82.183588,40.456212],[-82.194542,40.237135],[-82.75319,40.275473],[-82.742236,40.346673],[-82.621743,40.54932],[-82.336942,40.554797],[-82.221926,40.565751]]]}}, -{"type":"Feature","id":"39085","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-81.000569,41.852832],[-81.006046,41.715908],[-81.389431,41.568031],[-81.488016,41.633754],[-81.000569,41.852832]]]}}, -{"type":"Feature","id":"39087","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-82.649128,38.851469],[-82.577927,38.845992],[-82.28765,38.583099],[-82.506727,38.413313],[-82.561497,38.40236],[-82.594358,38.424267],[-82.665558,38.506421],[-82.813436,38.572145],[-82.649128,38.851469]]]}}, -{"type":"Feature","id":"39089","properties":{"name":"Licking"},"geometry":{"type":"Polygon","coordinates":[[[-82.75319,40.275473],[-82.194542,40.237135],[-82.189065,40.165934],[-82.23288,39.913995],[-82.462912,39.930426],[-82.780574,39.94138],[-82.764143,40.127596],[-82.75319,40.275473]]]}}, -{"type":"Feature","id":"39091","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-83.881439,40.538366],[-83.519961,40.505505],[-83.552823,40.231658],[-83.881439,40.264519],[-84.012886,40.275473],[-84.001932,40.483597],[-83.881439,40.538366]]]}}, -{"type":"Feature","id":"39093","properties":{"name":"Lorain"},"geometry":{"type":"Polygon","coordinates":[[[-81.969987,41.507785],[-81.876879,41.277753],[-82.172634,41.064153],[-82.336942,41.064153],[-82.342419,41.28323],[-82.347896,41.431108],[-81.969987,41.507785]]]}}, -{"type":"Feature","id":"39095","properties":{"name":"Lucas"},"geometry":{"type":"Polygon","coordinates":[[[-83.16396,41.6228],[-83.180391,41.6228],[-83.415899,41.617324],[-83.881439,41.414677],[-83.881439,41.485877],[-83.881439,41.721385],[-83.760947,41.721385],[-83.454238,41.732339],[-83.16396,41.6228]]]}}, -{"type":"Feature","id":"39097","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-83.50353,40.111165],[-83.207776,40.105688],[-83.246114,39.81541],[-83.246114,39.809933],[-83.251591,39.694917],[-83.651408,39.716825],[-83.645931,39.771595],[-83.514484,40.01258],[-83.50353,40.111165]]]}}, -{"type":"Feature","id":"39099","properties":{"name":"Mahoning"},"geometry":{"type":"Polygon","coordinates":[[[-80.786968,41.135353],[-80.518598,41.135353],[-80.518598,41.124399],[-80.518598,40.899844],[-80.858168,40.927229],[-81.0882,40.905321],[-81.0882,40.987475],[-81.000569,41.135353],[-80.786968,41.135353]]]}}, -{"type":"Feature","id":"39101","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-82.977744,40.702674],[-82.857251,40.702674],[-83.02156,40.434304],[-83.246114,40.445258],[-83.273499,40.505505],[-83.415899,40.505505],[-83.421376,40.686244],[-83.109191,40.702674],[-82.977744,40.702674]]]}}, -{"type":"Feature","id":"39103","properties":{"name":"Medina"},"geometry":{"type":"Polygon","coordinates":[[[-81.685186,41.277753],[-81.690663,40.987475],[-82.079526,40.992952],[-82.128818,40.992952],[-82.172634,41.064153],[-81.876879,41.277753],[-81.685186,41.277753]]]}}, -{"type":"Feature","id":"39105","properties":{"name":"Meigs"},"geometry":{"type":"Polygon","coordinates":[[[-82.28765,39.201993],[-82.271219,39.201993],[-81.756386,39.180085],[-81.745433,39.097931],[-81.909741,38.878853],[-82.101434,38.95553],[-82.320511,39.026731],[-82.28765,39.201993]]]}}, -{"type":"Feature","id":"39107","properties":{"name":"Mercer"},"geometry":{"type":"Polygon","coordinates":[[[-84.774181,40.730059],[-84.456518,40.686244],[-84.43461,40.35215],[-84.43461,40.35215],[-84.456518,40.35215],[-84.801565,40.35215],[-84.801565,40.571228],[-84.801565,40.730059],[-84.774181,40.730059]]]}}, -{"type":"Feature","id":"39109","properties":{"name":"Miami"},"geometry":{"type":"Polygon","coordinates":[[[-84.22101,40.198796],[-84.02384,40.182365],[-84.034794,40.039965],[-84.051224,39.881133],[-84.155286,39.924949],[-84.423656,39.919472],[-84.43461,40.198796],[-84.22101,40.198796]]]}}, -{"type":"Feature","id":"39111","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-81.307277,39.87018],[-81.236077,39.87018],[-80.81983,39.848272],[-80.830783,39.722302],[-80.945799,39.607286],[-81.038907,39.541563],[-81.28537,39.607286],[-81.307277,39.87018]]]}}, -{"type":"Feature","id":"39113","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-84.155286,39.924949],[-84.051224,39.881133],[-84.051224,39.848272],[-84.111471,39.579902],[-84.36341,39.590856],[-84.478426,39.590856],[-84.483903,39.919472],[-84.423656,39.919472],[-84.155286,39.924949]]]}}, -{"type":"Feature","id":"39115","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-82.074049,39.771595],[-81.69614,39.755164],[-81.586601,39.585379],[-81.844017,39.448455],[-82.046664,39.552517],[-82.074049,39.771595]]]}}, -{"type":"Feature","id":"39117","properties":{"name":"Morrow"},"geometry":{"type":"Polygon","coordinates":[[[-82.857251,40.713628],[-82.725805,40.713628],[-82.621743,40.54932],[-82.742236,40.346673],[-83.02156,40.434304],[-82.857251,40.702674],[-82.857251,40.713628]]]}}, -{"type":"Feature","id":"39119","properties":{"name":"Muskingum"},"geometry":{"type":"Polygon","coordinates":[[[-82.189065,40.165934],[-81.718048,40.149503],[-81.69614,39.842795],[-81.69614,39.755164],[-82.074049,39.771595],[-82.23288,39.913995],[-82.189065,40.165934]]]}}, -{"type":"Feature","id":"39121","properties":{"name":"Noble"},"geometry":{"type":"Polygon","coordinates":[[[-81.471585,39.892087],[-81.236077,39.952334],[-81.236077,39.87018],[-81.307277,39.87018],[-81.28537,39.607286],[-81.449678,39.634671],[-81.586601,39.585379],[-81.69614,39.755164],[-81.69614,39.842795],[-81.471585,39.892087]]]}}, -{"type":"Feature","id":"39123","properties":{"name":"Ottawa"},"geometry":{"type":"Polygon","coordinates":[[[-83.180391,41.6228],[-83.16396,41.6228],[-82.692943,41.491354],[-82.775097,41.4804],[-82.955836,41.458492],[-83.415899,41.502308],[-83.415899,41.617324],[-83.180391,41.6228]]]}}, -{"type":"Feature","id":"39125","properties":{"name":"Paulding"},"geometry":{"type":"Polygon","coordinates":[[[-84.577011,41.250368],[-84.341502,41.162737],[-84.401749,40.992952],[-84.456518,40.987475],[-84.801565,40.987475],[-84.801565,41.250368],[-84.577011,41.250368]]]}}, -{"type":"Feature","id":"39127","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-82.462912,39.930426],[-82.23288,39.913995],[-82.074049,39.771595],[-82.046664,39.552517],[-82.16168,39.557994],[-82.375281,39.656579],[-82.462912,39.930426]]]}}, -{"type":"Feature","id":"39129","properties":{"name":"Pickaway"},"geometry":{"type":"Polygon","coordinates":[[[-83.246114,39.809933],[-83.246114,39.81541],[-82.82439,39.793502],[-82.731282,39.552517],[-82.742236,39.470363],[-83.268022,39.514178],[-83.251591,39.694917],[-83.246114,39.809933]]]}}, -{"type":"Feature","id":"39131","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-83.355653,39.196516],[-82.786051,39.169131],[-82.807959,38.950054],[-83.273499,39.015777],[-83.383038,39.054115],[-83.355653,39.196516]]]}}, -{"type":"Feature","id":"39133","properties":{"name":"Portage"},"geometry":{"type":"Polygon","coordinates":[[[-81.389431,41.348953],[-81.000569,41.348953],[-81.000569,41.135353],[-81.0882,40.987475],[-81.394908,40.987475],[-81.389431,41.348953],[-81.389431,41.348953]]]}}, -{"type":"Feature","id":"39135","properties":{"name":"Preble"},"geometry":{"type":"Polygon","coordinates":[[[-84.483903,39.919472],[-84.478426,39.590856],[-84.812519,39.568948],[-84.812519,39.727779],[-84.812519,39.919472],[-84.483903,39.919472]]]}}, -{"type":"Feature","id":"39137","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-84.029317,41.168214],[-83.881439,41.168214],[-83.881439,40.921752],[-84.341502,40.861506],[-84.401749,40.992952],[-84.341502,41.162737],[-84.226487,41.168214],[-84.029317,41.168214]]]}}, -{"type":"Feature","id":"39139","properties":{"name":"Richland"},"geometry":{"type":"Polygon","coordinates":[[[-82.687466,40.992952],[-82.435527,40.992952],[-82.336942,40.554797],[-82.621743,40.54932],[-82.725805,40.713628],[-82.725805,40.998429],[-82.687466,40.992952]]]}}, -{"type":"Feature","id":"39141","properties":{"name":"Ross"},"geometry":{"type":"Polygon","coordinates":[[[-83.268022,39.514178],[-82.742236,39.470363],[-82.747713,39.366301],[-82.764143,39.20747],[-82.786051,39.169131],[-83.355653,39.196516],[-83.372084,39.377255],[-83.268022,39.514178]]]}}, -{"type":"Feature","id":"39143","properties":{"name":"Sandusky"},"geometry":{"type":"Polygon","coordinates":[[[-83.415899,41.502308],[-82.955836,41.458492],[-82.840821,41.288707],[-82.840821,41.255845],[-83.070852,41.255845],[-83.421376,41.255845],[-83.415899,41.502308]]]}}, -{"type":"Feature","id":"39145","properties":{"name":"Scioto"},"geometry":{"type":"Polygon","coordinates":[[[-83.273499,39.0103],[-83.273499,39.015777],[-82.807959,38.950054],[-82.649128,38.851469],[-82.813436,38.572145],[-83.032514,38.725499],[-83.268022,38.61596],[-83.273499,39.0103]]]}}, -{"type":"Feature","id":"39147","properties":{"name":"Seneca"},"geometry":{"type":"Polygon","coordinates":[[[-83.070852,41.255845],[-82.840821,41.255845],[-82.829867,40.998429],[-83.114668,40.992952],[-83.421376,40.992952],[-83.421376,41.168214],[-83.421376,41.255845],[-83.070852,41.255845]]]}}, -{"type":"Feature","id":"39149","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-84.105994,40.483597],[-84.001932,40.483597],[-84.012886,40.275473],[-84.02384,40.182365],[-84.22101,40.198796],[-84.43461,40.198796],[-84.43461,40.35215],[-84.43461,40.35215],[-84.105994,40.483597]]]}}, -{"type":"Feature","id":"39151","properties":{"name":"Stark"},"geometry":{"type":"Polygon","coordinates":[[[-81.394908,40.987475],[-81.0882,40.987475],[-81.0882,40.905321],[-81.0882,40.730059],[-81.121061,40.730059],[-81.318231,40.653382],[-81.42777,40.653382],[-81.652325,40.636951],[-81.652325,40.669813],[-81.646848,40.916275],[-81.394908,40.987475]]]}}, -{"type":"Feature","id":"39153","properties":{"name":"Summit"},"geometry":{"type":"Polygon","coordinates":[[[-81.537309,41.348953],[-81.389431,41.348953],[-81.394908,40.987475],[-81.646848,40.916275],[-81.690663,40.987475],[-81.685186,41.277753],[-81.537309,41.348953]]]}}, -{"type":"Feature","id":"39155","properties":{"name":"Trumbull"},"geometry":{"type":"Polygon","coordinates":[[[-81.000569,41.502308],[-80.518598,41.502308],[-80.518598,41.491354],[-80.518598,41.135353],[-80.786968,41.135353],[-81.000569,41.135353],[-81.000569,41.348953],[-81.000569,41.502308]]]}}, -{"type":"Feature","id":"39157","properties":{"name":"Tuscarawas"},"geometry":{"type":"Polygon","coordinates":[[[-81.42777,40.653382],[-81.318231,40.653382],[-81.268939,40.434304],[-81.340139,40.215227],[-81.62494,40.220704],[-81.707094,40.445258],[-81.652325,40.636951],[-81.42777,40.653382]]]}}, -{"type":"Feature","id":"39159","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-83.273499,40.505505],[-83.246114,40.445258],[-83.169437,40.144027],[-83.207776,40.105688],[-83.50353,40.111165],[-83.552823,40.231658],[-83.519961,40.505505],[-83.415899,40.505505],[-83.273499,40.505505]]]}}, -{"type":"Feature","id":"39161","properties":{"name":"Van Wert"},"geometry":{"type":"Polygon","coordinates":[[[-84.456518,40.987475],[-84.401749,40.992952],[-84.341502,40.861506],[-84.396272,40.686244],[-84.456518,40.686244],[-84.774181,40.730059],[-84.801565,40.730059],[-84.801565,40.921752],[-84.801565,40.987475],[-84.456518,40.987475]]]}}, -{"type":"Feature","id":"39163","properties":{"name":"Vinton"},"geometry":{"type":"Polygon","coordinates":[[[-82.747713,39.366301],[-82.28765,39.382732],[-82.271219,39.201993],[-82.28765,39.201993],[-82.320511,39.026731],[-82.435527,39.037685],[-82.671035,39.201993],[-82.764143,39.20747],[-82.747713,39.366301]]]}}, -{"type":"Feature","id":"39165","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-84.36341,39.590856],[-84.111471,39.579902],[-83.974547,39.568948],[-84.007409,39.256762],[-84.259348,39.273193],[-84.352456,39.289624],[-84.36341,39.590856]]]}}, -{"type":"Feature","id":"39167","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-81.449678,39.634671],[-81.28537,39.607286],[-81.038907,39.541563],[-81.121061,39.459409],[-81.373001,39.344393],[-81.723525,39.218424],[-81.844017,39.448455],[-81.586601,39.585379],[-81.449678,39.634671]]]}}, -{"type":"Feature","id":"39169","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-82.079526,40.992952],[-81.690663,40.987475],[-81.646848,40.916275],[-81.652325,40.669813],[-81.657801,40.669813],[-82.128818,40.669813],[-82.128818,40.992952],[-82.079526,40.992952]]]}}, -{"type":"Feature","id":"39171","properties":{"name":"Williams"},"geometry":{"type":"Polygon","coordinates":[[[-84.401749,41.704955],[-84.341502,41.485877],[-84.341502,41.425631],[-84.801565,41.425631],[-84.807042,41.529692],[-84.807042,41.694001],[-84.401749,41.704955]]]}}, -{"type":"Feature","id":"39173","properties":{"name":"Wood"},"geometry":{"type":"Polygon","coordinates":[[[-83.415899,41.617324],[-83.415899,41.502308],[-83.421376,41.255845],[-83.421376,41.168214],[-83.881439,41.168214],[-83.881439,41.414677],[-83.415899,41.617324]]]}}, -{"type":"Feature","id":"39175","properties":{"name":"Wyandot"},"geometry":{"type":"Polygon","coordinates":[[[-83.114668,40.992952],[-83.109191,40.702674],[-83.421376,40.686244],[-83.514484,40.81769],[-83.421376,40.992952],[-83.114668,40.992952]]]}}, -{"type":"Feature","id":"40001","properties":{"name":"Adair"},"geometry":{"type":"Polygon","coordinates":[[[-94.769597,36.162291],[-94.561473,36.162291],[-94.550519,36.102045],[-94.490273,35.756997],[-94.473842,35.636505],[-94.807935,35.636505],[-94.796981,36.162291],[-94.769597,36.162291]]]}}, -{"type":"Feature","id":"40003","properties":{"name":"Alfalfa"},"geometry":{"type":"Polygon","coordinates":[[[-98.543209,37.000263],[-98.346039,37.000263],[-98.11053,37.000263],[-98.105053,36.594969],[-98.105053,36.463523],[-98.532255,36.463523],[-98.543209,37.000263]]]}}, -{"type":"Feature","id":"40005","properties":{"name":"Atoka"},"geometry":{"type":"Polygon","coordinates":[[[-95.673292,34.595886],[-95.777354,34.157731],[-95.990954,34.157731],[-96.407202,34.157731],[-96.407202,34.420624],[-96.089539,34.67804],[-95.673292,34.595886]]]}}, -{"type":"Feature","id":"40007","properties":{"name":"Beaver"},"geometry":{"type":"Polygon","coordinates":[[[-100.087706,37.000263],[-100.000075,37.000263],[-100.005552,36.594969],[-100.005552,36.501861],[-100.547769,36.501861],[-100.805185,36.501861],[-100.953062,36.501861],[-100.947585,37.000263],[-100.6354,37.000263],[-100.087706,37.000263]]]}}, -{"type":"Feature","id":"40009","properties":{"name":"Beckham"},"geometry":{"type":"Polygon","coordinates":[[[-99.36475,35.510535],[-99.36475,35.466719],[-99.359273,35.116195],[-99.408565,35.116195],[-99.709797,35.116195],[-99.890536,35.028564],[-99.934351,35.028564],[-100.000075,35.028564],[-100.000075,35.181919],[-100.000075,35.422904],[-99.36475,35.510535]]]}}, -{"type":"Feature","id":"40011","properties":{"name":"Blaine"},"geometry":{"type":"Polygon","coordinates":[[[-98.488439,36.162291],[-98.209115,36.162291],[-98.209115,35.724136],[-98.313177,35.548874],[-98.587024,35.548874],[-98.625363,35.548874],[-98.63084,35.811767],[-98.636317,36.162291],[-98.488439,36.162291]]]}}, -{"type":"Feature","id":"40013","properties":{"name":"Bryan"},"geometry":{"type":"Polygon","coordinates":[[[-96.412679,34.157731],[-96.407202,34.157731],[-95.990954,34.157731],[-95.760923,33.87293],[-95.843077,33.840068],[-96.379817,33.725052],[-96.587941,33.894838],[-96.587941,34.113915],[-96.412679,34.157731]]]}}, -{"type":"Feature","id":"40015","properties":{"name":"Caddo"},"geometry":{"type":"Polygon","coordinates":[[[-98.587024,35.548874],[-98.313177,35.548874],[-98.0941,35.379088],[-98.0941,34.853302],[-98.619886,34.853302],[-98.619886,35.099764],[-98.625363,35.466719],[-98.625363,35.548874],[-98.587024,35.548874]]]}}, -{"type":"Feature","id":"40017","properties":{"name":"Canadian"},"geometry":{"type":"Polygon","coordinates":[[[-97.973607,35.724136],[-97.672375,35.724136],[-97.672375,35.379088],[-97.672375,35.335273],[-97.672375,35.335273],[-98.0941,35.379088],[-98.313177,35.548874],[-98.209115,35.724136],[-97.973607,35.724136]]]}}, -{"type":"Feature","id":"40019","properties":{"name":"Carter"},"geometry":{"type":"Polygon","coordinates":[[[-97.562836,34.508255],[-97.354713,34.508255],[-96.932988,34.332993],[-96.932988,34.174162],[-96.971327,34.0701],[-97.562836,34.0701],[-97.562836,34.289177],[-97.562836,34.508255]]]}}, -{"type":"Feature","id":"40021","properties":{"name":"Cherokee"},"geometry":{"type":"Polygon","coordinates":[[[-95.027013,36.162291],[-95.010582,36.162291],[-94.796981,36.162291],[-94.807935,35.636505],[-94.851751,35.636505],[-95.125598,35.636505],[-95.267998,35.811767],[-95.207752,36.07466],[-95.027013,36.162291]]]}}, -{"type":"Feature","id":"40023","properties":{"name":"Choctaw"},"geometry":{"type":"Polygon","coordinates":[[[-95.383014,34.157731],[-95.158459,34.157731],[-95.158459,33.938653],[-95.311814,33.878407],[-95.760923,33.87293],[-95.990954,34.157731],[-95.777354,34.157731],[-95.383014,34.157731]]]}}, -{"type":"Feature","id":"40025","properties":{"name":"Cimarron"},"geometry":{"type":"Polygon","coordinates":[[[-102.042974,36.994786],[-102.026543,36.994786],[-102.03202,36.501861],[-102.163466,36.501861],[-103.001438,36.501861],[-103.001438,37.000263],[-102.042974,36.994786]]]}}, -{"type":"Feature","id":"40027","properties":{"name":"Cleveland"},"geometry":{"type":"Polygon","coordinates":[[[-97.425913,35.379088],[-97.141112,35.379088],[-97.141112,34.929979],[-97.672375,35.335273],[-97.672375,35.379088],[-97.425913,35.379088]]]}}, -{"type":"Feature","id":"40029","properties":{"name":"Coal"},"geometry":{"type":"Polygon","coordinates":[[[-96.089539,34.765671],[-96.089539,34.67804],[-96.407202,34.420624],[-96.511264,34.502778],[-96.407202,34.765671],[-96.089539,34.765671]]]}}, -{"type":"Feature","id":"40031","properties":{"name":"Comanche"},"geometry":{"type":"Polygon","coordinates":[[[-98.795148,34.853302],[-98.619886,34.853302],[-98.0941,34.853302],[-98.088623,34.683517],[-98.143392,34.508255],[-98.663701,34.404193],[-98.82801,34.595886],[-98.795148,34.853302]]]}}, -{"type":"Feature","id":"40033","properties":{"name":"Cotton"},"geometry":{"type":"Polygon","coordinates":[[[-98.143392,34.508255],[-98.137915,34.289177],[-98.137915,34.1413],[-98.422716,34.081054],[-98.608932,34.157731],[-98.663701,34.404193],[-98.143392,34.508255],[-98.143392,34.508255]]]}}, -{"type":"Feature","id":"40035","properties":{"name":"Craig"},"geometry":{"type":"Polygon","coordinates":[[[-95.152983,37.000263],[-95.070828,37.000263],[-95.005105,37.000263],[-94.999628,36.671646],[-95.005105,36.507338],[-95.322768,36.512815],[-95.328245,36.512815],[-95.432306,36.594969],[-95.410399,37.000263],[-95.152983,37.000263]]]}}, -{"type":"Feature","id":"40037","properties":{"name":"Creek"},"geometry":{"type":"Polygon","coordinates":[[[-96.620803,36.162291],[-96.297663,36.162291],[-96.03477,35.855582],[-96.138832,35.855582],[-96.193601,35.636505],[-96.478402,35.636505],[-96.620803,35.636505],[-96.620803,35.943213],[-96.620803,36.162291]]]}}, -{"type":"Feature","id":"40039","properties":{"name":"Custer"},"geometry":{"type":"Polygon","coordinates":[[[-98.817056,35.811767],[-98.63084,35.811767],[-98.625363,35.548874],[-98.625363,35.466719],[-99.16758,35.466719],[-99.36475,35.466719],[-99.36475,35.510535],[-99.375704,35.811767],[-98.817056,35.811767]]]}}, -{"type":"Feature","id":"40041","properties":{"name":"Delaware"},"geometry":{"type":"Polygon","coordinates":[[[-94.890089,36.671646],[-94.616242,36.666169],[-94.616242,36.501861],[-94.561473,36.162291],[-94.769597,36.162291],[-94.796981,36.162291],[-95.010582,36.162291],[-95.005105,36.507338],[-94.999628,36.671646],[-94.890089,36.671646]]]}}, -{"type":"Feature","id":"40043","properties":{"name":"Dewey"},"geometry":{"type":"Polygon","coordinates":[[[-98.636317,36.162291],[-98.63084,35.811767],[-98.817056,35.811767],[-99.375704,35.811767],[-99.38118,36.014414],[-99.38118,36.162291],[-98.953979,36.162291],[-98.636317,36.162291]]]}}, -{"type":"Feature","id":"40045","properties":{"name":"Ellis"},"geometry":{"type":"Polygon","coordinates":[[[-99.605735,36.594969],[-99.38118,36.162291],[-99.38118,36.014414],[-100.000075,35.882967],[-100.000075,36.058229],[-100.005552,36.501861],[-100.005552,36.594969],[-99.605735,36.594969]]]}}, -{"type":"Feature","id":"40047","properties":{"name":"Garfield"},"geometry":{"type":"Polygon","coordinates":[[[-97.984561,36.594969],[-97.464251,36.594969],[-97.464251,36.594969],[-97.458774,36.162291],[-97.677852,36.162291],[-98.0941,36.167768],[-98.105053,36.162291],[-98.105053,36.463523],[-98.105053,36.594969],[-97.984561,36.594969]]]}}, -{"type":"Feature","id":"40049","properties":{"name":"Garvin"},"geometry":{"type":"Polygon","coordinates":[[[-97.425913,34.853302],[-96.932988,34.853302],[-96.932988,34.634225],[-97.091819,34.639701],[-97.354713,34.508255],[-97.562836,34.508255],[-97.666898,34.683517],[-97.666898,34.853302],[-97.425913,34.853302]]]}}, -{"type":"Feature","id":"40051","properties":{"name":"Grady"},"geometry":{"type":"Polygon","coordinates":[[[-98.0941,35.379088],[-97.672375,35.335273],[-97.666898,34.853302],[-97.666898,34.683517],[-97.995515,34.683517],[-98.088623,34.683517],[-98.0941,34.853302],[-98.0941,35.379088]]]}}, -{"type":"Feature","id":"40053","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-97.650467,37.000263],[-97.464251,37.000263],[-97.464251,36.594969],[-97.984561,36.594969],[-98.105053,36.594969],[-98.11053,37.000263],[-97.803822,37.000263],[-97.650467,37.000263]]]}}, -{"type":"Feature","id":"40055","properties":{"name":"Greer"},"geometry":{"type":"Polygon","coordinates":[[[-99.709797,35.116195],[-99.408565,35.116195],[-99.244257,34.820441],[-99.397611,34.814964],[-99.665981,34.727333],[-99.890536,35.028564],[-99.709797,35.116195]]]}}, -{"type":"Feature","id":"40057","properties":{"name":"Harmon"},"geometry":{"type":"Polygon","coordinates":[[[-99.934351,35.028564],[-99.890536,35.028564],[-99.665981,34.727333],[-99.84672,34.508255],[-100.000075,34.563024],[-100.000075,34.743763],[-100.000075,35.028564],[-99.934351,35.028564]]]}}, -{"type":"Feature","id":"40059","properties":{"name":"Harper"},"geometry":{"type":"Polygon","coordinates":[[[-100.000075,37.000263],[-99.540012,37.000263],[-99.457858,37.000263],[-99.293549,36.819524],[-99.605735,36.594969],[-100.005552,36.594969],[-100.000075,37.000263]]]}}, -{"type":"Feature","id":"40061","properties":{"name":"Haskell"},"geometry":{"type":"Polygon","coordinates":[[[-95.048921,35.461243],[-94.813412,35.324319],[-94.928428,35.055949],[-95.333722,35.055949],[-95.350152,35.055949],[-95.448737,35.296934],[-95.344675,35.291457],[-95.048921,35.461243]]]}}, -{"type":"Feature","id":"40063","properties":{"name":"Hughes"},"geometry":{"type":"Polygon","coordinates":[[[-96.199078,35.291457],[-95.980001,35.291457],[-95.985477,35.149057],[-96.089539,34.765671],[-96.407202,34.765671],[-96.489356,34.908072],[-96.440064,35.291457],[-96.199078,35.291457]]]}}, -{"type":"Feature","id":"40065","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-99.397611,34.814964],[-99.244257,34.820441],[-99.101857,34.639701],[-99.211395,34.33847],[-99.474288,34.398716],[-99.84672,34.508255],[-99.665981,34.727333],[-99.397611,34.814964]]]}}, -{"type":"Feature","id":"40067","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-98.061238,34.289177],[-97.562836,34.289177],[-97.562836,34.0701],[-97.562836,33.894838],[-97.979084,33.889361],[-98.137915,34.1413],[-98.137915,34.289177],[-98.061238,34.289177]]]}}, -{"type":"Feature","id":"40069","properties":{"name":"Johnston"},"geometry":{"type":"Polygon","coordinates":[[[-96.878219,34.502778],[-96.828926,34.508255],[-96.511264,34.502778],[-96.407202,34.420624],[-96.407202,34.157731],[-96.412679,34.157731],[-96.587941,34.113915],[-96.932988,34.174162],[-96.932988,34.332993],[-96.878219,34.502778]]]}}, -{"type":"Feature","id":"40071","properties":{"name":"Kay"},"geometry":{"type":"Polygon","coordinates":[[[-96.867265,37.000263],[-96.752249,37.000263],[-97.058958,36.594969],[-97.464251,36.594969],[-97.464251,36.594969],[-97.464251,37.000263],[-97.146589,37.000263],[-96.867265,37.000263]]]}}, -{"type":"Feature","id":"40073","properties":{"name":"Kingfisher"},"geometry":{"type":"Polygon","coordinates":[[[-98.0941,36.167768],[-97.677852,36.162291],[-97.672375,35.724136],[-97.973607,35.724136],[-98.209115,35.724136],[-98.209115,36.162291],[-98.105053,36.162291],[-98.0941,36.167768]]]}}, -{"type":"Feature","id":"40075","properties":{"name":"Kiowa"},"geometry":{"type":"Polygon","coordinates":[[[-99.184011,35.116195],[-98.619886,35.099764],[-98.619886,34.853302],[-98.795148,34.853302],[-98.82801,34.595886],[-99.101857,34.639701],[-99.244257,34.820441],[-99.408565,35.116195],[-99.359273,35.116195],[-99.184011,35.116195]]]}}, -{"type":"Feature","id":"40077","properties":{"name":"Latimer"},"geometry":{"type":"Polygon","coordinates":[[[-95.333722,35.055949],[-94.928428,35.055949],[-95.059875,34.67804],[-95.311814,34.683517],[-95.514461,34.683517],[-95.350152,35.055949],[-95.333722,35.055949]]]}}, -{"type":"Feature","id":"40079","properties":{"name":"Le Flore"},"geometry":{"type":"Polygon","coordinates":[[[-94.430026,35.379088],[-94.446457,34.935456],[-94.451934,34.727333],[-94.462888,34.508255],[-94.616242,34.508255],[-94.939382,34.508255],[-95.059875,34.67804],[-94.928428,35.055949],[-94.813412,35.324319],[-94.430026,35.379088]]]}}, -{"type":"Feature","id":"40081","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-97.080866,35.943213],[-96.620803,35.943213],[-96.620803,35.636505],[-96.626279,35.461243],[-97.141112,35.466719],[-97.141112,35.724136],[-97.141112,35.943213],[-97.080866,35.943213]]]}}, -{"type":"Feature","id":"40083","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-97.677852,36.162291],[-97.458774,36.162291],[-97.354713,36.156814],[-97.141112,35.943213],[-97.141112,35.724136],[-97.672375,35.724136],[-97.677852,36.162291]]]}}, -{"type":"Feature","id":"40085","properties":{"name":"Love"},"geometry":{"type":"Polygon","coordinates":[[[-97.562836,34.0701],[-96.971327,34.0701],[-96.932988,33.955084],[-96.943942,33.949607],[-97.486159,33.916745],[-97.562836,33.894838],[-97.562836,34.0701]]]}}, -{"type":"Feature","id":"40087","properties":{"name":"McClain"},"geometry":{"type":"Polygon","coordinates":[[[-97.672375,35.335273],[-97.141112,34.929979],[-96.932988,34.962841],[-96.932988,34.853302],[-97.425913,34.853302],[-97.666898,34.853302],[-97.672375,35.335273],[-97.672375,35.335273]]]}}, -{"type":"Feature","id":"40089","properties":{"name":"McCurtain"},"geometry":{"type":"Polygon","coordinates":[[[-94.616242,34.508255],[-94.462888,34.508255],[-94.468365,34.190592],[-94.479319,33.938653],[-94.484796,33.637421],[-94.736735,33.703145],[-95.158459,33.938653],[-95.158459,34.157731],[-94.939382,34.508255],[-94.616242,34.508255]]]}}, -{"type":"Feature","id":"40091","properties":{"name":"McIntosh"},"geometry":{"type":"Polygon","coordinates":[[[-95.476122,35.554351],[-95.344675,35.291457],[-95.448737,35.296934],[-95.706154,35.203826],[-95.985477,35.149057],[-95.980001,35.291457],[-95.980001,35.379088],[-95.71163,35.554351],[-95.476122,35.554351]]]}}, -{"type":"Feature","id":"40093","properties":{"name":"Major"},"geometry":{"type":"Polygon","coordinates":[[[-98.959456,36.501861],[-98.959456,36.507338],[-98.532255,36.463523],[-98.105053,36.463523],[-98.105053,36.162291],[-98.209115,36.162291],[-98.488439,36.162291],[-98.636317,36.162291],[-98.953979,36.162291],[-98.959456,36.501861]]]}}, -{"type":"Feature","id":"40095","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-96.932988,34.174162],[-96.587941,34.113915],[-96.587941,33.894838],[-96.932988,33.955084],[-96.971327,34.0701],[-96.932988,34.174162]]]}}, -{"type":"Feature","id":"40097","properties":{"name":"Mayes"},"geometry":{"type":"Polygon","coordinates":[[[-95.322768,36.512815],[-95.005105,36.507338],[-95.010582,36.162291],[-95.027013,36.162291],[-95.207752,36.07466],[-95.437783,36.07466],[-95.328245,36.512815],[-95.322768,36.512815]]]}}, -{"type":"Feature","id":"40099","properties":{"name":"Murray"},"geometry":{"type":"Polygon","coordinates":[[[-97.091819,34.639701],[-96.932988,34.634225],[-96.828926,34.508255],[-96.878219,34.502778],[-96.932988,34.332993],[-97.354713,34.508255],[-97.091819,34.639701]]]}}, -{"type":"Feature","id":"40101","properties":{"name":"Muskogee"},"geometry":{"type":"Polygon","coordinates":[[[-95.656861,35.855582],[-95.267998,35.811767],[-95.125598,35.636505],[-95.048921,35.461243],[-95.344675,35.291457],[-95.476122,35.554351],[-95.71163,35.554351],[-95.7664,35.855582],[-95.656861,35.855582]]]}}, -{"type":"Feature","id":"40103","properties":{"name":"Noble"},"geometry":{"type":"Polygon","coordinates":[[[-97.464251,36.594969],[-97.058958,36.594969],[-97.009665,36.507338],[-96.927511,36.244445],[-97.031573,36.244445],[-97.354713,36.156814],[-97.458774,36.162291],[-97.464251,36.594969]]]}}, -{"type":"Feature","id":"40105","properties":{"name":"Nowata"},"geometry":{"type":"Polygon","coordinates":[[[-95.613046,37.000263],[-95.519938,37.000263],[-95.410399,37.000263],[-95.432306,36.594969],[-95.810215,36.594969],[-95.788308,37.000263],[-95.613046,37.000263]]]}}, -{"type":"Feature","id":"40107","properties":{"name":"Okfuskee"},"geometry":{"type":"Polygon","coordinates":[[[-96.478402,35.636505],[-96.193601,35.636505],[-95.980001,35.379088],[-95.980001,35.291457],[-96.199078,35.291457],[-96.440064,35.291457],[-96.440064,35.466719],[-96.626279,35.400996],[-96.626279,35.461243],[-96.620803,35.636505],[-96.478402,35.636505]]]}}, -{"type":"Feature","id":"40109","properties":{"name":"Oklahoma"},"geometry":{"type":"Polygon","coordinates":[[[-97.672375,35.724136],[-97.141112,35.724136],[-97.141112,35.466719],[-97.141112,35.379088],[-97.425913,35.379088],[-97.672375,35.379088],[-97.672375,35.724136]]]}}, -{"type":"Feature","id":"40111","properties":{"name":"Okmulgee"},"geometry":{"type":"Polygon","coordinates":[[[-96.138832,35.855582],[-96.03477,35.855582],[-95.821169,35.855582],[-95.7664,35.855582],[-95.71163,35.554351],[-95.980001,35.379088],[-96.193601,35.636505],[-96.138832,35.855582]]]}}, -{"type":"Feature","id":"40113","properties":{"name":"Osage"},"geometry":{"type":"Polygon","coordinates":[[[-96.730341,37.000263],[-96.527695,37.000263],[-96.001908,37.000263],[-96.001908,36.425184],[-96.270278,36.162291],[-96.724864,36.529246],[-97.009665,36.507338],[-97.058958,36.594969],[-96.752249,37.000263],[-96.730341,37.000263]]]}}, -{"type":"Feature","id":"40115","properties":{"name":"Ottawa"},"geometry":{"type":"Polygon","coordinates":[[[-94.994151,37.000263],[-94.616242,37.000263],[-94.616242,36.764754],[-94.616242,36.666169],[-94.890089,36.671646],[-94.999628,36.671646],[-95.005105,37.000263],[-94.994151,37.000263]]]}}, -{"type":"Feature","id":"40117","properties":{"name":"Pawnee"},"geometry":{"type":"Polygon","coordinates":[[[-96.724864,36.529246],[-96.270278,36.162291],[-96.297663,36.162291],[-96.620803,36.162291],[-96.927511,36.244445],[-97.009665,36.507338],[-96.724864,36.529246]]]}}, -{"type":"Feature","id":"40119","properties":{"name":"Payne"},"geometry":{"type":"Polygon","coordinates":[[[-97.031573,36.244445],[-96.927511,36.244445],[-96.620803,36.162291],[-96.620803,35.943213],[-97.080866,35.943213],[-97.141112,35.943213],[-97.354713,36.156814],[-97.031573,36.244445]]]}}, -{"type":"Feature","id":"40121","properties":{"name":"Pittsburg"},"geometry":{"type":"Polygon","coordinates":[[[-95.706154,35.203826],[-95.448737,35.296934],[-95.350152,35.055949],[-95.514461,34.683517],[-95.673292,34.595886],[-96.089539,34.67804],[-96.089539,34.765671],[-95.985477,35.149057],[-95.706154,35.203826]]]}}, -{"type":"Feature","id":"40123","properties":{"name":"Pontotoc"},"geometry":{"type":"Polygon","coordinates":[[[-96.932988,34.962841],[-96.774157,34.902595],[-96.489356,34.908072],[-96.407202,34.765671],[-96.511264,34.502778],[-96.828926,34.508255],[-96.932988,34.634225],[-96.932988,34.853302],[-96.932988,34.962841]]]}}, -{"type":"Feature","id":"40125","properties":{"name":"Pottawatomie"},"geometry":{"type":"Polygon","coordinates":[[[-97.141112,35.466719],[-96.626279,35.461243],[-96.626279,35.400996],[-96.774157,34.902595],[-96.932988,34.962841],[-97.141112,34.929979],[-97.141112,35.379088],[-97.141112,35.466719]]]}}, -{"type":"Feature","id":"40127","properties":{"name":"Pushmataha"},"geometry":{"type":"Polygon","coordinates":[[[-95.311814,34.683517],[-95.059875,34.67804],[-94.939382,34.508255],[-95.158459,34.157731],[-95.383014,34.157731],[-95.777354,34.157731],[-95.673292,34.595886],[-95.514461,34.683517],[-95.311814,34.683517]]]}}, -{"type":"Feature","id":"40129","properties":{"name":"Roger Mills"},"geometry":{"type":"Polygon","coordinates":[[[-99.38118,36.014414],[-99.375704,35.811767],[-99.36475,35.510535],[-100.000075,35.422904],[-100.000075,35.620074],[-100.000075,35.882967],[-99.38118,36.014414]]]}}, -{"type":"Feature","id":"40131","properties":{"name":"Rogers"},"geometry":{"type":"Polygon","coordinates":[[[-95.810215,36.594969],[-95.432306,36.594969],[-95.328245,36.512815],[-95.437783,36.07466],[-95.618522,36.162291],[-95.760923,36.162291],[-95.810215,36.425184],[-95.810215,36.594969]]]}}, -{"type":"Feature","id":"40133","properties":{"name":"Seminole"},"geometry":{"type":"Polygon","coordinates":[[[-96.440064,35.466719],[-96.440064,35.291457],[-96.489356,34.908072],[-96.774157,34.902595],[-96.626279,35.400996],[-96.440064,35.466719]]]}}, -{"type":"Feature","id":"40135","properties":{"name":"Sequoyah"},"geometry":{"type":"Polygon","coordinates":[[[-94.851751,35.636505],[-94.807935,35.636505],[-94.473842,35.636505],[-94.430026,35.395519],[-94.430026,35.379088],[-94.813412,35.324319],[-95.048921,35.461243],[-95.125598,35.636505],[-94.851751,35.636505]]]}}, -{"type":"Feature","id":"40137","properties":{"name":"Stephens"},"geometry":{"type":"Polygon","coordinates":[[[-97.995515,34.683517],[-97.666898,34.683517],[-97.562836,34.508255],[-97.562836,34.289177],[-98.061238,34.289177],[-98.137915,34.289177],[-98.143392,34.508255],[-98.143392,34.508255],[-98.088623,34.683517],[-97.995515,34.683517]]]}}, -{"type":"Feature","id":"40139","properties":{"name":"Texas"},"geometry":{"type":"Polygon","coordinates":[[[-100.947585,37.000263],[-100.953062,36.501861],[-101.084509,36.501861],[-101.621249,36.501861],[-101.812942,36.501861],[-102.03202,36.501861],[-102.026543,36.994786],[-101.555526,36.994786],[-101.068078,37.000263],[-100.947585,37.000263]]]}}, -{"type":"Feature","id":"40141","properties":{"name":"Tillman"},"geometry":{"type":"Polygon","coordinates":[[[-99.101857,34.639701],[-98.82801,34.595886],[-98.663701,34.404193],[-98.608932,34.157731],[-98.953979,34.2125],[-99.211395,34.33847],[-99.101857,34.639701]]]}}, -{"type":"Feature","id":"40143","properties":{"name":"Tulsa"},"geometry":{"type":"Polygon","coordinates":[[[-95.919754,36.425184],[-95.810215,36.425184],[-95.760923,36.162291],[-95.821169,35.855582],[-96.03477,35.855582],[-96.297663,36.162291],[-96.270278,36.162291],[-96.001908,36.425184],[-95.919754,36.425184]]]}}, -{"type":"Feature","id":"40145","properties":{"name":"Wagoner"},"geometry":{"type":"Polygon","coordinates":[[[-95.618522,36.162291],[-95.437783,36.07466],[-95.207752,36.07466],[-95.267998,35.811767],[-95.656861,35.855582],[-95.7664,35.855582],[-95.821169,35.855582],[-95.760923,36.162291],[-95.618522,36.162291]]]}}, -{"type":"Feature","id":"40147","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-95.9088,37.000263],[-95.788308,37.000263],[-95.810215,36.594969],[-95.810215,36.425184],[-95.919754,36.425184],[-96.001908,36.425184],[-96.001908,37.000263],[-95.96357,37.000263],[-95.9088,37.000263]]]}}, -{"type":"Feature","id":"40149","properties":{"name":"Washita"},"geometry":{"type":"Polygon","coordinates":[[[-99.16758,35.466719],[-98.625363,35.466719],[-98.619886,35.099764],[-99.184011,35.116195],[-99.359273,35.116195],[-99.36475,35.466719],[-99.16758,35.466719]]]}}, -{"type":"Feature","id":"40151","properties":{"name":"Woods"},"geometry":{"type":"Polygon","coordinates":[[[-99.457858,37.000263],[-99.003272,37.000263],[-98.543209,37.000263],[-98.532255,36.463523],[-98.959456,36.507338],[-99.293549,36.819524],[-99.457858,37.000263]]]}}, -{"type":"Feature","id":"40153","properties":{"name":"Woodward"},"geometry":{"type":"Polygon","coordinates":[[[-99.293549,36.819524],[-98.959456,36.507338],[-98.959456,36.501861],[-98.953979,36.162291],[-99.38118,36.162291],[-99.605735,36.594969],[-99.293549,36.819524]]]}}, -{"type":"Feature","id":"41001","properties":{"name":"Baker"},"geometry":{"type":"Polygon","coordinates":[[[-117.778223,44.991119],[-117.268868,45.07875],[-116.78142,45.07875],[-116.901913,44.843241],[-117.219575,44.301024],[-117.608438,44.443425],[-118.232809,44.257209],[-118.495702,44.257209],[-118.243763,44.958257],[-117.778223,44.991119]]]}}, -{"type":"Feature","id":"41003","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-123.561872,44.722749],[-123.151102,44.722749],[-123.200394,44.284593],[-123.775473,44.284593],[-123.600211,44.722749],[-123.561872,44.722749]]]}}, -{"type":"Feature","id":"41005","properties":{"name":"Clackamas"},"geometry":{"type":"Polygon","coordinates":[[[-122.356945,45.462136],[-121.820205,45.462136],[-121.694236,45.259489],[-121.732574,44.887057],[-122.395284,44.887057],[-122.84987,45.259489],[-122.866301,45.319735],[-122.745808,45.434751],[-122.356945,45.462136]]]}}, -{"type":"Feature","id":"41007","properties":{"name":"Clatsop"},"geometry":{"type":"Polygon","coordinates":[[[-123.364702,46.146753],[-123.359225,45.779798],[-123.841196,45.785275],[-123.967166,45.785275],[-124.010981,46.22343],[-123.545441,46.261769],[-123.364702,46.146753]]]}}, -{"type":"Feature","id":"41009","properties":{"name":"Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-122.784147,45.850998],[-122.762239,45.730506],[-122.926547,45.725029],[-123.134671,45.779798],[-123.359225,45.779798],[-123.364702,46.146753],[-123.211348,46.174138],[-122.784147,45.850998]]]}}, -{"type":"Feature","id":"41011","properties":{"name":"Coos"},"geometry":{"type":"Polygon","coordinates":[[[-124.147905,43.61093],[-123.874058,43.61093],[-123.813811,42.789389],[-124.295782,42.953697],[-124.481998,42.953697],[-124.219105,43.61093],[-124.147905,43.61093]]]}}, -{"type":"Feature","id":"41013","properties":{"name":"Crook"},"geometry":{"type":"Polygon","coordinates":[[[-120.385247,44.563917],[-119.656814,44.306501],[-119.656814,43.961454],[-119.897799,43.698561],[-120.98771,43.961454],[-121.108203,44.388655],[-120.385247,44.563917]]]}}, -{"type":"Feature","id":"41015","properties":{"name":"Curry"},"geometry":{"type":"Polygon","coordinates":[[[-124.295782,42.953697],[-123.813811,42.789389],[-123.715227,42.783912],[-124.027412,42.35671],[-123.819288,41.995232],[-124.213628,42.000709],[-124.481998,42.953697],[-124.295782,42.953697]]]}}, -{"type":"Feature","id":"41017","properties":{"name":"Deschutes"},"geometry":{"type":"Polygon","coordinates":[[[-121.108203,44.388655],[-120.98771,43.961454],[-119.897799,43.698561],[-119.897799,43.61093],[-121.130111,43.616407],[-121.332757,43.616407],[-121.486112,43.616407],[-122.000944,43.616407],[-121.798297,44.257209],[-121.842113,44.394132],[-121.108203,44.388655]]]}}, -{"type":"Feature","id":"41019","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-123.824765,43.945023],[-123.140148,43.780715],[-123.107286,43.53973],[-122.132391,43.441145],[-122.280268,42.997512],[-123.227779,42.701758],[-123.715227,42.783912],[-123.813811,42.789389],[-123.874058,43.61093],[-124.147905,43.61093],[-124.219105,43.61093],[-124.158859,43.862869],[-123.824765,43.945023]]]}}, -{"type":"Feature","id":"41021","properties":{"name":"Gilliam"},"geometry":{"type":"Polygon","coordinates":[[[-120.653617,45.735983],[-120.001861,45.81266],[-119.78826,45.067796],[-119.870414,45.067796],[-120.494786,45.067796],[-120.505739,45.084227],[-120.653617,45.735983]]]}}, -{"type":"Feature","id":"41023","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-118.676441,44.996596],[-118.51761,44.996596],[-118.243763,44.958257],[-118.495702,44.257209],[-118.232809,44.257209],[-118.227332,44.038131],[-118.468318,44.038131],[-119.656814,43.961454],[-119.656814,44.306501],[-119.673245,44.996596],[-119.163889,44.996596],[-118.676441,44.996596]]]}}, -{"type":"Feature","id":"41025","properties":{"name":"Harney"},"geometry":{"type":"Polygon","coordinates":[[[-118.468318,44.038131],[-118.227332,44.038131],[-118.194471,41.995232],[-119.32272,41.995232],[-119.361059,41.995232],[-119.366536,42.75105],[-119.941615,42.745573],[-119.897799,43.61093],[-119.897799,43.698561],[-119.656814,43.961454],[-118.468318,44.038131]]]}}, -{"type":"Feature","id":"41027","properties":{"name":"Hood River"},"geometry":{"type":"Polygon","coordinates":[[[-121.924267,45.648352],[-121.52445,45.725029],[-121.442296,45.697644],[-121.694236,45.259489],[-121.820205,45.462136],[-121.924267,45.648352]]]}}, -{"type":"Feature","id":"41029","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-122.280268,42.992036],[-122.291222,42.006186],[-123.233256,42.006186],[-123.227779,42.701758],[-122.280268,42.997512],[-122.280268,42.992036]]]}}, -{"type":"Feature","id":"41031","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-120.998664,44.821334],[-120.374293,44.821334],[-120.385247,44.563917],[-121.108203,44.388655],[-121.842113,44.394132],[-121.79282,44.68441],[-121.759959,44.826811],[-120.998664,44.821334]]]}}, -{"type":"Feature","id":"41033","properties":{"name":"Josephine"},"geometry":{"type":"Polygon","coordinates":[[[-123.715227,42.783912],[-123.227779,42.701758],[-123.233256,42.006186],[-123.518057,42.000709],[-123.819288,41.995232],[-124.027412,42.35671],[-123.715227,42.783912]]]}}, -{"type":"Feature","id":"41035","properties":{"name":"Klamath"},"geometry":{"type":"Polygon","coordinates":[[[-121.486112,43.616407],[-121.332757,43.616407],[-121.349188,42.745573],[-120.883648,42.745573],[-120.878171,41.995232],[-121.316327,41.995232],[-121.447773,41.995232],[-122.291222,42.006186],[-122.280268,42.992036],[-122.280268,42.997512],[-122.132391,43.441145],[-122.000944,43.616407],[-121.486112,43.616407]]]}}, -{"type":"Feature","id":"41037","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-121.130111,43.616407],[-119.897799,43.61093],[-119.941615,42.745573],[-119.366536,42.75105],[-119.361059,41.995232],[-120.001861,41.995232],[-120.878171,41.995232],[-120.883648,42.745573],[-121.349188,42.745573],[-121.332757,43.616407],[-121.130111,43.616407]]]}}, -{"type":"Feature","id":"41039","properties":{"name":"Lane"},"geometry":{"type":"Polygon","coordinates":[[[-124.010981,44.279117],[-123.775473,44.284593],[-123.200394,44.284593],[-121.798297,44.257209],[-122.000944,43.616407],[-122.132391,43.441145],[-123.107286,43.53973],[-123.140148,43.780715],[-123.824765,43.945023],[-124.158859,43.862869],[-124.115043,44.27364],[-124.010981,44.279117]]]}}, -{"type":"Feature","id":"41041","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-124.000027,45.045888],[-123.72618,45.045888],[-123.600211,44.722749],[-123.775473,44.284593],[-124.010981,44.279117],[-124.115043,44.27364],[-124.005504,45.045888],[-124.000027,45.045888]]]}}, -{"type":"Feature","id":"41043","properties":{"name":"Linn"},"geometry":{"type":"Polygon","coordinates":[[[-122.658177,44.777518],[-121.79282,44.68441],[-121.842113,44.394132],[-121.798297,44.257209],[-123.200394,44.284593],[-123.151102,44.722749],[-123.145625,44.750133],[-122.658177,44.777518]]]}}, -{"type":"Feature","id":"41045","properties":{"name":"Malheur"},"geometry":{"type":"Polygon","coordinates":[[[-117.608438,44.443425],[-117.219575,44.301024],[-116.896436,44.153147],[-116.97859,43.8793],[-117.027882,43.68213],[-117.027882,42.000709],[-118.194471,41.995232],[-118.227332,44.038131],[-118.232809,44.257209],[-117.608438,44.443425]]]}}, -{"type":"Feature","id":"41047","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-122.964886,45.286874],[-122.84987,45.259489],[-122.395284,44.887057],[-121.732574,44.887057],[-121.759959,44.826811],[-121.79282,44.68441],[-122.658177,44.777518],[-123.145625,44.750133],[-123.068948,45.073273],[-122.964886,45.286874]]]}}, -{"type":"Feature","id":"41049","properties":{"name":"Morrow"},"geometry":{"type":"Polygon","coordinates":[[[-119.432259,45.916722],[-119.147458,45.516905],[-119.163889,44.996596],[-119.673245,44.996596],[-119.78826,45.067796],[-120.001861,45.81266],[-119.870414,45.834568],[-119.432259,45.916722]]]}}, -{"type":"Feature","id":"41051","properties":{"name":"Multnomah"},"geometry":{"type":"Polygon","coordinates":[[[-122.926547,45.725029],[-122.762239,45.730506],[-122.247407,45.549767],[-121.924267,45.648352],[-121.820205,45.462136],[-122.356945,45.462136],[-122.745808,45.434751],[-122.926547,45.725029]]]}}, -{"type":"Feature","id":"41053","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-123.622119,45.07875],[-123.068948,45.073273],[-123.145625,44.750133],[-123.151102,44.722749],[-123.561872,44.722749],[-123.600211,44.722749],[-123.72618,45.045888],[-123.72618,45.07875],[-123.622119,45.07875]]]}}, -{"type":"Feature","id":"41055","properties":{"name":"Sherman"},"geometry":{"type":"Polygon","coordinates":[[[-120.834356,45.675736],[-120.653617,45.735983],[-120.505739,45.084227],[-121.026049,45.22115],[-120.91651,45.642875],[-120.834356,45.675736]]]}}, -{"type":"Feature","id":"41057","properties":{"name":"Tillamook"},"geometry":{"type":"Polygon","coordinates":[[[-123.841196,45.785275],[-123.359225,45.779798],[-123.463287,45.434751],[-123.72618,45.07875],[-123.72618,45.045888],[-124.000027,45.045888],[-124.005504,45.045888],[-123.967166,45.785275],[-123.841196,45.785275]]]}}, -{"type":"Feature","id":"41059","properties":{"name":"Umatilla"},"geometry":{"type":"Polygon","coordinates":[[[-118.58881,45.998876],[-117.997301,45.998876],[-117.975393,45.998876],[-117.975393,45.861952],[-118.117793,45.47309],[-118.698349,45.34712],[-118.51761,44.996596],[-118.676441,44.996596],[-119.163889,44.996596],[-119.147458,45.516905],[-119.432259,45.916722],[-118.988627,45.998876],[-118.58881,45.998876]]]}}, -{"type":"Feature","id":"41061","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-117.898716,45.861952],[-117.268868,45.07875],[-117.778223,44.991119],[-118.243763,44.958257],[-118.51761,44.996596],[-118.698349,45.34712],[-118.117793,45.47309],[-117.975393,45.861952],[-117.898716,45.861952]]]}}, -{"type":"Feature","id":"41063","properties":{"name":"Wallowa"},"geometry":{"type":"Polygon","coordinates":[[[-117.975393,45.998876],[-117.602961,45.998876],[-117.482468,45.998876],[-116.918344,45.993399],[-116.792374,45.856475],[-116.463758,45.61549],[-116.688312,45.270443],[-116.78142,45.07875],[-117.268868,45.07875],[-117.898716,45.861952],[-117.975393,45.861952],[-117.975393,45.998876]]]}}, -{"type":"Feature","id":"41065","properties":{"name":"Wasco"},"geometry":{"type":"Polygon","coordinates":[[[-121.442296,45.697644],[-120.91651,45.642875],[-121.026049,45.22115],[-120.505739,45.084227],[-120.494786,45.067796],[-120.374293,44.821334],[-120.998664,44.821334],[-121.759959,44.826811],[-121.732574,44.887057],[-121.694236,45.259489],[-121.442296,45.697644]]]}}, -{"type":"Feature","id":"41067","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-123.134671,45.779798],[-122.926547,45.725029],[-122.745808,45.434751],[-122.866301,45.319735],[-123.063471,45.401889],[-123.463287,45.434751],[-123.359225,45.779798],[-123.134671,45.779798]]]}}, -{"type":"Feature","id":"41069","properties":{"name":"Wheeler"},"geometry":{"type":"Polygon","coordinates":[[[-119.870414,45.067796],[-119.78826,45.067796],[-119.673245,44.996596],[-119.656814,44.306501],[-120.385247,44.563917],[-120.374293,44.821334],[-120.494786,45.067796],[-119.870414,45.067796]]]}}, -{"type":"Feature","id":"41071","properties":{"name":"Yamhill"},"geometry":{"type":"Polygon","coordinates":[[[-123.063471,45.401889],[-122.866301,45.319735],[-122.84987,45.259489],[-122.964886,45.286874],[-123.068948,45.073273],[-123.622119,45.07875],[-123.72618,45.07875],[-123.463287,45.434751],[-123.063471,45.401889]]]}}, -{"type":"Feature","id":"42001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-77.139326,40.067349],[-76.996925,39.722302],[-77.216003,39.722302],[-77.456988,39.722302],[-77.473419,39.946857],[-77.139326,40.067349]]]}}, -{"type":"Feature","id":"42003","properties":{"name":"Allegheny"},"geometry":{"type":"Polygon","coordinates":[[[-80.146166,40.67529],[-79.69158,40.669813],[-79.69158,40.669813],[-79.872319,40.198796],[-80.359767,40.47812],[-80.146166,40.67529]]]}}, -{"type":"Feature","id":"42005","properties":{"name":"Armstrong"},"geometry":{"type":"Polygon","coordinates":[[[-79.603949,41.020337],[-79.215086,41.053199],[-79.215086,40.910798],[-79.450595,40.527412],[-79.538226,40.54932],[-79.69158,40.669813],[-79.69158,40.669813],[-79.69158,41.168214],[-79.603949,41.020337]]]}}, -{"type":"Feature","id":"42007","properties":{"name":"Beaver"},"geometry":{"type":"Polygon","coordinates":[[[-80.255705,40.856029],[-80.15712,40.856029],[-80.146166,40.67529],[-80.359767,40.47812],[-80.398105,40.47812],[-80.518598,40.47812],[-80.518598,40.636951],[-80.518598,40.850552],[-80.255705,40.856029]]]}}, -{"type":"Feature","id":"42009","properties":{"name":"Bedford"},"geometry":{"type":"Polygon","coordinates":[[[-78.6181,40.324766],[-78.256622,40.297381],[-78.136129,40.165934],[-78.382591,39.722302],[-78.809792,39.722302],[-78.656438,40.242611],[-78.6181,40.324766]]]}}, -{"type":"Feature","id":"42011","properties":{"name":"Berks"},"geometry":{"type":"Polygon","coordinates":[[[-75.890583,40.67529],[-75.529105,40.445258],[-75.69889,40.242611],[-75.874152,40.13855],[-76.153476,40.313812],[-76.438277,40.494551],[-75.890583,40.67529]]]}}, -{"type":"Feature","id":"42013","properties":{"name":"Blair"},"geometry":{"type":"Polygon","coordinates":[[[-78.360683,40.735536],[-78.114221,40.741013],[-78.256622,40.297381],[-78.6181,40.324766],[-78.349729,40.724582],[-78.360683,40.735536]]]}}, -{"type":"Feature","id":"42015","properties":{"name":"Bradford"},"geometry":{"type":"Polygon","coordinates":[[[-76.920248,42.000709],[-76.55877,42.000709],[-76.147999,42.000709],[-76.115138,41.650185],[-76.2192,41.540646],[-76.816186,41.589939],[-76.876433,41.595416],[-76.925725,42.000709],[-76.920248,42.000709]]]}}, -{"type":"Feature","id":"42017","properties":{"name":"Bucks"},"geometry":{"type":"Polygon","coordinates":[[[-75.195012,40.609566],[-75.189535,40.593136],[-74.943073,40.341196],[-74.723995,40.149503],[-74.975934,40.050919],[-75.014273,40.13855],[-75.48529,40.417874],[-75.331935,40.538366],[-75.195012,40.609566]]]}}, -{"type":"Feature","id":"42019","properties":{"name":"Butler"},"geometry":{"type":"Polygon","coordinates":[[[-79.998289,41.173691],[-79.697057,41.173691],[-79.69158,41.168214],[-79.69158,40.669813],[-80.146166,40.67529],[-80.15712,40.856029],[-80.096873,41.069629],[-79.998289,41.173691]]]}}, -{"type":"Feature","id":"42021","properties":{"name":"Cambria"},"geometry":{"type":"Polygon","coordinates":[[[-78.804316,40.724582],[-78.349729,40.724582],[-78.6181,40.324766],[-78.656438,40.242611],[-79.001485,40.286427],[-79.056255,40.286427],[-78.974101,40.395966],[-78.804316,40.724582]]]}}, -{"type":"Feature","id":"42023","properties":{"name":"Cameron"},"geometry":{"type":"Polygon","coordinates":[[[-78.42093,41.600893],[-78.201852,41.617324],[-77.988251,41.474923],[-78.092313,41.217507],[-78.234714,41.228461],[-78.42093,41.600893]]]}}, -{"type":"Feature","id":"42025","properties":{"name":"Carbon"},"geometry":{"type":"Polygon","coordinates":[[[-75.687936,41.129876],[-75.649598,41.124399],[-75.474336,40.812213],[-75.611259,40.784829],[-75.759137,40.735536],[-75.994645,40.910798],[-75.687936,41.129876]]]}}, -{"type":"Feature","id":"42027","properties":{"name":"Centre"},"geometry":{"type":"Polygon","coordinates":[[[-77.708927,41.113445],[-77.144803,41.042245],[-77.36388,40.845075],[-77.681543,40.730059],[-78.114221,40.741013],[-78.360683,40.735536],[-78.037544,41.151784],[-77.708927,41.113445]]]}}, -{"type":"Feature","id":"42029","properties":{"name":"Chester"},"geometry":{"type":"Polygon","coordinates":[[[-75.676983,40.242611],[-75.35932,40.067349],[-75.594828,39.837318],[-75.786521,39.722302],[-75.808429,39.722302],[-76.137046,39.722302],[-75.874152,40.13855],[-75.69889,40.242611],[-75.676983,40.242611]]]}}, -{"type":"Feature","id":"42031","properties":{"name":"Clarion"},"geometry":{"type":"Polygon","coordinates":[[[-79.357487,41.431108],[-79.209609,41.332523],[-79.215086,41.053199],[-79.603949,41.020337],[-79.69158,41.168214],[-79.697057,41.173691],[-79.477979,41.387292],[-79.357487,41.431108]]]}}, -{"type":"Feature","id":"42033","properties":{"name":"Clearfield"},"geometry":{"type":"Polygon","coordinates":[[[-78.234714,41.228461],[-78.092313,41.217507],[-78.037544,41.151784],[-78.360683,40.735536],[-78.349729,40.724582],[-78.804316,40.724582],[-78.804316,40.905321],[-78.711208,41.201076],[-78.234714,41.228461]]]}}, -{"type":"Feature","id":"42035","properties":{"name":"Clinton"},"geometry":{"type":"Polygon","coordinates":[[[-77.747266,41.474923],[-77.599389,41.4804],[-77.144803,41.069629],[-77.144803,41.042245],[-77.708927,41.113445],[-78.037544,41.151784],[-78.092313,41.217507],[-77.988251,41.474923],[-77.747266,41.474923]]]}}, -{"type":"Feature","id":"42037","properties":{"name":"Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-76.317785,41.310615],[-76.312308,41.310615],[-76.208246,40.949137],[-76.378031,40.773875],[-76.525908,40.883413],[-76.640924,41.157261],[-76.449231,41.277753],[-76.317785,41.310615]]]}}, -{"type":"Feature","id":"42039","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-79.708011,41.852832],[-79.609426,41.847355],[-79.614903,41.6228],[-79.998289,41.491354],[-80.003765,41.491354],[-80.518598,41.491354],[-80.518598,41.502308],[-80.518598,41.847355],[-79.708011,41.852832]]]}}, -{"type":"Feature","id":"42041","properties":{"name":"Cumberland"},"geometry":{"type":"Polygon","coordinates":[[[-77.122895,40.297381],[-76.914771,40.330243],[-76.860002,40.226181],[-76.903817,40.220704],[-77.139326,40.067349],[-77.473419,39.946857],[-77.615819,40.198796],[-77.122895,40.297381]]]}}, -{"type":"Feature","id":"42043","properties":{"name":"Dauphin"},"geometry":{"type":"Polygon","coordinates":[[[-76.536862,40.554797],[-76.564247,40.198796],[-76.723078,40.122119],[-76.860002,40.226181],[-76.914771,40.330243],[-76.95311,40.60409],[-76.947633,40.625997],[-76.70117,40.658859],[-76.536862,40.554797]]]}}, -{"type":"Feature","id":"42045","properties":{"name":"Delaware"},"geometry":{"type":"Polygon","coordinates":[[[-75.353843,40.056395],[-75.277166,39.974241],[-75.211443,39.864703],[-75.414089,39.804456],[-75.578398,39.837318],[-75.594828,39.837318],[-75.594828,39.837318],[-75.35932,40.067349],[-75.353843,40.056395]]]}}, -{"type":"Feature","id":"42047","properties":{"name":"Elk"},"geometry":{"type":"Polygon","coordinates":[[[-78.95767,41.6228],[-78.42093,41.600893],[-78.234714,41.228461],[-78.711208,41.201076],[-78.95767,41.370861],[-79.094593,41.343476],[-78.95767,41.6228]]]}}, -{"type":"Feature","id":"42049","properties":{"name":"Erie"},"geometry":{"type":"Polygon","coordinates":[[[-79.76278,42.252649],[-79.609426,42.000709],[-79.609426,41.847355],[-79.708011,41.852832],[-80.518598,41.847355],[-80.518598,41.978802],[-80.518598,41.978802],[-79.76278,42.269079],[-79.76278,42.252649]]]}}, -{"type":"Feature","id":"42051","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-79.499887,40.13855],[-79.291763,40.039965],[-79.390348,39.722302],[-79.477979,39.722302],[-79.609426,39.722302],[-79.76278,39.722302],[-79.916134,39.722302],[-79.998289,39.985195],[-79.877796,40.127596],[-79.499887,40.13855]]]}}, -{"type":"Feature","id":"42053","properties":{"name":"Forest"},"geometry":{"type":"Polygon","coordinates":[[[-78.996008,41.6228],[-78.95767,41.6228],[-79.094593,41.343476],[-79.209609,41.332523],[-79.357487,41.431108],[-79.477979,41.387292],[-79.510841,41.6228],[-78.996008,41.6228]]]}}, -{"type":"Feature","id":"42055","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-77.670589,40.291904],[-77.615819,40.198796],[-77.473419,39.946857],[-77.456988,39.722302],[-77.467942,39.722302],[-78.09779,39.722302],[-77.862282,40.061872],[-77.703451,40.264519],[-77.670589,40.291904]]]}}, -{"type":"Feature","id":"42057","properties":{"name":"Fulton"},"geometry":{"type":"Polygon","coordinates":[[[-78.136129,40.165934],[-77.862282,40.061872],[-78.09779,39.722302],[-78.284006,39.722302],[-78.344253,39.722302],[-78.382591,39.722302],[-78.136129,40.165934]]]}}, -{"type":"Feature","id":"42059","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-80.064012,40.007103],[-79.998289,39.985195],[-79.916134,39.722302],[-80.420013,39.722302],[-80.518598,39.722302],[-80.518598,39.963288],[-80.064012,40.007103]]]}}, -{"type":"Feature","id":"42061","properties":{"name":"Huntingdon"},"geometry":{"type":"Polygon","coordinates":[[[-78.114221,40.741013],[-77.681543,40.730059],[-77.752743,40.379535],[-77.703451,40.264519],[-77.862282,40.061872],[-78.136129,40.165934],[-78.256622,40.297381],[-78.114221,40.741013]]]}}, -{"type":"Feature","id":"42063","properties":{"name":"Indiana"},"geometry":{"type":"Polygon","coordinates":[[[-79.215086,40.910798],[-78.804316,40.905321],[-78.804316,40.724582],[-78.974101,40.395966],[-79.450595,40.527412],[-79.215086,40.910798]]]}}, -{"type":"Feature","id":"42065","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-78.95767,41.370861],[-78.711208,41.201076],[-78.804316,40.905321],[-79.215086,40.910798],[-79.215086,41.053199],[-79.209609,41.332523],[-79.094593,41.343476],[-78.95767,41.370861]]]}}, -{"type":"Feature","id":"42067","properties":{"name":"Juniata"},"geometry":{"type":"Polygon","coordinates":[[[-77.133849,40.686244],[-76.936679,40.636951],[-76.947633,40.625997],[-77.670589,40.291904],[-77.703451,40.264519],[-77.752743,40.379535],[-77.287203,40.691721],[-77.133849,40.686244]]]}}, -{"type":"Feature","id":"42069","properties":{"name":"Lackawanna"},"geometry":{"type":"Polygon","coordinates":[[[-75.720798,41.644708],[-75.463382,41.639231],[-75.507197,41.233938],[-75.600305,41.162737],[-75.835814,41.425631],[-75.720798,41.644708]]]}}, -{"type":"Feature","id":"42071","properties":{"name":"Lancaster"},"geometry":{"type":"Polygon","coordinates":[[[-76.306831,40.253565],[-76.153476,40.313812],[-75.874152,40.13855],[-76.137046,39.722302],[-76.235631,39.722302],[-76.241107,39.722302],[-76.723078,40.122119],[-76.564247,40.198796],[-76.306831,40.253565]]]}}, -{"type":"Feature","id":"42073","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-80.518598,41.124399],[-80.096873,41.069629],[-80.15712,40.856029],[-80.255705,40.856029],[-80.518598,40.850552],[-80.518598,40.899844],[-80.518598,41.124399]]]}}, -{"type":"Feature","id":"42075","properties":{"name":"Lebanon"},"geometry":{"type":"Polygon","coordinates":[[[-76.536862,40.554797],[-76.438277,40.494551],[-76.153476,40.313812],[-76.306831,40.253565],[-76.564247,40.198796],[-76.536862,40.554797]]]}}, -{"type":"Feature","id":"42077","properties":{"name":"Lehigh"},"geometry":{"type":"Polygon","coordinates":[[[-75.611259,40.784829],[-75.331935,40.538366],[-75.48529,40.417874],[-75.490767,40.423351],[-75.529105,40.445258],[-75.890583,40.67529],[-75.759137,40.735536],[-75.611259,40.784829]]]}}, -{"type":"Feature","id":"42079","properties":{"name":"Luzerne"},"geometry":{"type":"Polygon","coordinates":[[[-75.835814,41.425631],[-75.835814,41.425631],[-75.600305,41.162737],[-75.649598,41.124399],[-75.687936,41.129876],[-75.994645,40.910798],[-76.208246,40.949137],[-76.312308,41.310615],[-76.284923,41.376338],[-75.835814,41.425631]]]}}, -{"type":"Feature","id":"42081","properties":{"name":"Lycoming"},"geometry":{"type":"Polygon","coordinates":[[[-76.876433,41.595416],[-76.816186,41.589939],[-76.449231,41.277753],[-76.640924,41.157261],[-76.734032,41.173691],[-76.799755,41.173691],[-76.89834,41.14083],[-77.144803,41.069629],[-77.599389,41.4804],[-77.599389,41.540646],[-76.876433,41.595416]]]}}, -{"type":"Feature","id":"42083","properties":{"name":"McKean"},"geometry":{"type":"Polygon","coordinates":[[[-78.919331,42.000709],[-78.305914,42.000709],[-78.207329,42.000709],[-78.201852,41.617324],[-78.42093,41.600893],[-78.95767,41.6228],[-78.919331,42.000709]]]}}, -{"type":"Feature","id":"42085","properties":{"name":"Mercer"},"geometry":{"type":"Polygon","coordinates":[[[-80.003765,41.491354],[-79.998289,41.491354],[-79.998289,41.173691],[-80.096873,41.069629],[-80.518598,41.124399],[-80.518598,41.135353],[-80.518598,41.491354],[-80.003765,41.491354]]]}}, -{"type":"Feature","id":"42087","properties":{"name":"Mifflin"},"geometry":{"type":"Polygon","coordinates":[[[-77.36388,40.845075],[-77.358403,40.806736],[-77.287203,40.691721],[-77.752743,40.379535],[-77.681543,40.730059],[-77.36388,40.845075]]]}}, -{"type":"Feature","id":"42089","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-75.271689,41.244892],[-74.992365,41.091537],[-74.96498,41.097014],[-75.118335,40.965568],[-75.474336,40.812213],[-75.649598,41.124399],[-75.600305,41.162737],[-75.507197,41.233938],[-75.35932,41.239415],[-75.271689,41.244892]]]}}, -{"type":"Feature","id":"42091","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-75.490767,40.423351],[-75.48529,40.417874],[-75.014273,40.13855],[-75.025227,40.133073],[-75.277166,39.974241],[-75.353843,40.056395],[-75.35932,40.067349],[-75.676983,40.242611],[-75.69889,40.242611],[-75.529105,40.445258],[-75.490767,40.423351]]]}}, -{"type":"Feature","id":"42093","properties":{"name":"Montour"},"geometry":{"type":"Polygon","coordinates":[[[-76.734032,41.173691],[-76.640924,41.157261],[-76.525908,40.883413],[-76.734032,41.173691]]]}}, -{"type":"Feature","id":"42095","properties":{"name":"Northampton"},"geometry":{"type":"Polygon","coordinates":[[[-75.118335,40.965568],[-75.195012,40.609566],[-75.331935,40.538366],[-75.611259,40.784829],[-75.474336,40.812213],[-75.118335,40.965568]]]}}, -{"type":"Feature","id":"42097","properties":{"name":"Northumberland"},"geometry":{"type":"Polygon","coordinates":[[[-76.799755,41.173691],[-76.734032,41.173691],[-76.525908,40.883413],[-76.378031,40.773875],[-76.70117,40.658859],[-76.947633,40.625997],[-76.936679,40.636951],[-76.799755,40.883413],[-76.89834,41.14083],[-76.799755,41.173691]]]}}, -{"type":"Feature","id":"42099","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-76.95311,40.60409],[-76.914771,40.330243],[-77.122895,40.297381],[-77.615819,40.198796],[-77.670589,40.291904],[-76.947633,40.625997],[-76.95311,40.60409]]]}}, -{"type":"Feature","id":"42101","properties":{"name":"Philadelphia"},"geometry":{"type":"Polygon","coordinates":[[[-75.025227,40.133073],[-75.014273,40.13855],[-74.975934,40.050919],[-75.058088,39.990672],[-75.140242,39.88661],[-75.211443,39.864703],[-75.277166,39.974241],[-75.025227,40.133073]]]}}, -{"type":"Feature","id":"42103","properties":{"name":"Pike"},"geometry":{"type":"Polygon","coordinates":[[[-75.069042,41.600893],[-74.756857,41.425631],[-74.69661,41.359907],[-74.992365,41.091537],[-75.271689,41.244892],[-75.35932,41.239415],[-75.069042,41.600893]]]}}, -{"type":"Feature","id":"42105","properties":{"name":"Potter"},"geometry":{"type":"Polygon","coordinates":[[[-78.207329,42.000709],[-77.747266,42.000709],[-77.610343,42.000709],[-77.599389,41.540646],[-77.599389,41.4804],[-77.747266,41.474923],[-77.988251,41.474923],[-78.201852,41.617324],[-78.207329,42.000709]]]}}, -{"type":"Feature","id":"42107","properties":{"name":"Schuylkill"},"geometry":{"type":"Polygon","coordinates":[[[-76.208246,40.949137],[-75.994645,40.910798],[-75.759137,40.735536],[-75.890583,40.67529],[-76.438277,40.494551],[-76.536862,40.554797],[-76.70117,40.658859],[-76.378031,40.773875],[-76.208246,40.949137]]]}}, -{"type":"Feature","id":"42109","properties":{"name":"Snyder"},"geometry":{"type":"Polygon","coordinates":[[[-76.854525,40.88889],[-76.799755,40.883413],[-76.936679,40.636951],[-77.133849,40.686244],[-77.287203,40.691721],[-77.358403,40.806736],[-76.854525,40.88889]]]}}, -{"type":"Feature","id":"42111","properties":{"name":"Somerset"},"geometry":{"type":"Polygon","coordinates":[[[-79.001485,40.286427],[-78.656438,40.242611],[-78.809792,39.722302],[-78.930285,39.722302],[-79.390348,39.722302],[-79.291763,40.039965],[-79.056255,40.286427],[-79.001485,40.286427]]]}}, -{"type":"Feature","id":"42113","properties":{"name":"Sullivan"},"geometry":{"type":"Polygon","coordinates":[[[-76.816186,41.589939],[-76.2192,41.540646],[-76.284923,41.376338],[-76.312308,41.310615],[-76.317785,41.310615],[-76.449231,41.277753],[-76.816186,41.589939]]]}}, -{"type":"Feature","id":"42115","properties":{"name":"Susquehanna"},"geometry":{"type":"Polygon","coordinates":[[[-75.890583,42.000709],[-75.48529,42.000709],[-75.463382,41.639231],[-75.720798,41.644708],[-76.115138,41.650185],[-76.147999,42.000709],[-76.104184,42.000709],[-75.890583,42.000709]]]}}, -{"type":"Feature","id":"42117","properties":{"name":"Tioga"},"geometry":{"type":"Polygon","coordinates":[[[-76.925725,42.000709],[-76.876433,41.595416],[-77.599389,41.540646],[-77.610343,42.000709],[-76.964064,42.000709],[-76.925725,42.000709]]]}}, -{"type":"Feature","id":"42119","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-77.144803,41.069629],[-76.89834,41.14083],[-76.799755,40.883413],[-76.854525,40.88889],[-77.358403,40.806736],[-77.36388,40.845075],[-77.144803,41.042245],[-77.144803,41.069629]]]}}, -{"type":"Feature","id":"42121","properties":{"name":"Venango"},"geometry":{"type":"Polygon","coordinates":[[[-79.510841,41.6228],[-79.477979,41.387292],[-79.697057,41.173691],[-79.998289,41.173691],[-79.998289,41.491354],[-79.614903,41.6228],[-79.510841,41.6228]]]}}, -{"type":"Feature","id":"42123","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-79.061732,42.000709],[-78.919331,42.000709],[-78.95767,41.6228],[-78.996008,41.6228],[-79.510841,41.6228],[-79.614903,41.6228],[-79.609426,41.847355],[-79.609426,42.000709],[-79.061732,42.000709]]]}}, -{"type":"Feature","id":"42125","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-80.398105,40.47812],[-80.359767,40.47812],[-79.872319,40.198796],[-79.877796,40.127596],[-79.998289,39.985195],[-80.064012,40.007103],[-80.518598,39.963288],[-80.518598,40.018057],[-80.518598,40.160457],[-80.518598,40.401443],[-80.518598,40.47812],[-80.398105,40.47812]]]}}, -{"type":"Feature","id":"42127","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-75.479813,42.000709],[-75.35932,42.000709],[-75.145719,41.852832],[-75.069042,41.600893],[-75.35932,41.239415],[-75.507197,41.233938],[-75.463382,41.639231],[-75.48529,42.000709],[-75.479813,42.000709]]]}}, -{"type":"Feature","id":"42129","properties":{"name":"Westmoreland"},"geometry":{"type":"Polygon","coordinates":[[[-79.538226,40.54932],[-79.450595,40.527412],[-78.974101,40.395966],[-79.056255,40.286427],[-79.291763,40.039965],[-79.499887,40.13855],[-79.877796,40.127596],[-79.872319,40.198796],[-79.69158,40.669813],[-79.538226,40.54932]]]}}, -{"type":"Feature","id":"42131","properties":{"name":"Wyoming"},"geometry":{"type":"Polygon","coordinates":[[[-76.2192,41.540646],[-76.115138,41.650185],[-75.720798,41.644708],[-75.835814,41.425631],[-75.835814,41.425631],[-76.284923,41.376338],[-76.2192,41.540646]]]}}, -{"type":"Feature","id":"42133","properties":{"name":"York"},"geometry":{"type":"Polygon","coordinates":[[[-76.903817,40.220704],[-76.860002,40.226181],[-76.723078,40.122119],[-76.241107,39.722302],[-76.569724,39.722302],[-76.70117,39.722302],[-76.788801,39.722302],[-76.996925,39.722302],[-77.139326,40.067349],[-76.903817,40.220704]]]}}, -{"type":"Feature","id":"44001","properties":{"name":"Bristol"},"geometry":{"type":"Polygon","coordinates":[[[-71.317338,41.776155],[-71.22423,41.710431],[-71.355677,41.726862],[-71.366631,41.737816],[-71.317338,41.776155]]]}}, -{"type":"Feature","id":"44003","properties":{"name":"Kent"},"geometry":{"type":"Polygon","coordinates":[[[-71.4214,41.765201],[-71.366631,41.737816],[-71.355677,41.726862],[-71.410446,41.655662],[-71.470692,41.633754],[-71.788355,41.595416],[-71.788355,41.639231],[-71.788355,41.726862],[-71.4214,41.765201]]]}}, -{"type":"Feature","id":"44007","properties":{"name":"Providence"},"geometry":{"type":"Polygon","coordinates":[[[-71.498077,42.01714],[-71.383061,41.984279],[-71.317338,41.776155],[-71.366631,41.737816],[-71.4214,41.765201],[-71.788355,41.726862],[-71.799309,42.006186],[-71.498077,42.01714]]]}}, -{"type":"Feature","id":"44009","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-71.470692,41.633754],[-71.410446,41.655662],[-71.859555,41.321569],[-71.788355,41.595416],[-71.470692,41.633754]]]}}, -{"type":"Feature","id":"45001","properties":{"name":"Abbeville"},"geometry":{"type":"Polygon","coordinates":[[[-82.325988,34.475393],[-82.315034,34.486347],[-82.243834,34.40967],[-82.325988,34.064623],[-82.594358,34.01533],[-82.742236,34.207023],[-82.325988,34.475393]]]}}, -{"type":"Feature","id":"45003","properties":{"name":"Aiken"},"geometry":{"type":"Polygon","coordinates":[[[-81.57017,33.878407],[-81.186785,33.653852],[-81.373001,33.489544],[-81.756386,33.199266],[-81.849494,33.248559],[-82.013803,33.53336],[-81.652325,33.812683],[-81.57017,33.878407]]]}}, -{"type":"Feature","id":"45005","properties":{"name":"Allendale"},"geometry":{"type":"Polygon","coordinates":[[[-81.613986,33.095204],[-81.192262,33.117112],[-81.082723,33.024004],[-81.411339,32.74468],[-81.542786,33.045912],[-81.613986,33.095204]]]}}, -{"type":"Feature","id":"45007","properties":{"name":"Anderson"},"geometry":{"type":"Polygon","coordinates":[[[-82.490296,34.820441],[-82.484819,34.820441],[-82.315034,34.486347],[-82.325988,34.475393],[-82.742236,34.207023],[-82.775097,34.289177],[-82.994175,34.48087],[-82.857251,34.60684],[-82.846298,34.617794],[-82.840821,34.623271],[-82.490296,34.820441]]]}}, -{"type":"Feature","id":"45009","properties":{"name":"Bamberg"},"geometry":{"type":"Polygon","coordinates":[[[-81.10463,33.380005],[-80.797922,33.177358],[-81.082723,33.024004],[-81.192262,33.117112],[-81.225123,33.440252],[-81.10463,33.380005]]]}}, -{"type":"Feature","id":"45011","properties":{"name":"Barnwell"},"geometry":{"type":"Polygon","coordinates":[[[-81.373001,33.489544],[-81.225123,33.440252],[-81.192262,33.117112],[-81.613986,33.095204],[-81.756386,33.199266],[-81.373001,33.489544]]]}}, -{"type":"Feature","id":"45013","properties":{"name":"Beaufort"},"geometry":{"type":"Polygon","coordinates":[[[-80.825307,32.706342],[-80.474782,32.487264],[-80.880076,32.08197],[-80.869122,32.662526],[-80.825307,32.706342]]]}}, -{"type":"Feature","id":"45015","properties":{"name":"Berkeley"},"geometry":{"type":"Polygon","coordinates":[[[-80.053058,33.505975],[-79.675149,33.303328],[-79.445118,33.215697],[-79.49441,33.188312],[-79.927088,32.821357],[-80.151643,33.024004],[-80.359767,33.259513],[-80.222843,33.445728],[-80.10235,33.495021],[-80.053058,33.505975]]]}}, -{"type":"Feature","id":"45017","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-81.044384,33.796253],[-81.011523,33.878407],[-80.62266,33.741483],[-80.535029,33.642898],[-80.49669,33.560744],[-81.044384,33.708622],[-81.044384,33.796253]]]}}, -{"type":"Feature","id":"45019","properties":{"name":"Charleston"},"geometry":{"type":"Polygon","coordinates":[[[-79.49441,33.188312],[-79.445118,33.215697],[-79.291763,33.111635],[-80.250228,32.531079],[-80.403582,32.859696],[-80.151643,33.024004],[-79.927088,32.821357],[-79.49441,33.188312]]]}}, -{"type":"Feature","id":"45021","properties":{"name":"Cherokee"},"geometry":{"type":"Polygon","coordinates":[[[-81.76734,35.181919],[-81.367524,35.165488],[-81.455155,34.836871],[-81.712571,34.913548],[-81.876879,35.181919],[-81.76734,35.181919]]]}}, -{"type":"Feature","id":"45023","properties":{"name":"Chester"},"geometry":{"type":"Polygon","coordinates":[[[-81.28537,34.820441],[-80.896507,34.820441],[-80.880076,34.541117],[-81.416816,34.573978],[-81.422293,34.573978],[-81.477062,34.820441],[-81.28537,34.820441]]]}}, -{"type":"Feature","id":"45025","properties":{"name":"Chesterfield"},"geometry":{"type":"Polygon","coordinates":[[[-80.562413,34.814964],[-80.321428,34.814964],[-79.927088,34.80401],[-79.828503,34.530163],[-79.866842,34.508255],[-80.288566,34.365854],[-80.387151,34.595886],[-80.409059,34.612317],[-80.562413,34.814964]]]}}, -{"type":"Feature","id":"45027","properties":{"name":"Clarendon"},"geometry":{"type":"Polygon","coordinates":[[[-80.332382,33.779822],[-79.976381,33.94413],[-79.877796,33.883884],[-80.10235,33.495021],[-80.222843,33.445728],[-80.49669,33.560744],[-80.535029,33.642898],[-80.332382,33.779822]]]}}, -{"type":"Feature","id":"45029","properties":{"name":"Colleton"},"geometry":{"type":"Polygon","coordinates":[[[-80.792445,33.182835],[-80.403582,32.859696],[-80.250228,32.531079],[-80.474782,32.487264],[-80.825307,32.706342],[-81.055338,33.002096],[-81.082723,33.024004],[-80.797922,33.177358],[-80.792445,33.182835]]]}}, -{"type":"Feature","id":"45031","properties":{"name":"Darlington"},"geometry":{"type":"Polygon","coordinates":[[[-79.866842,34.508255],[-79.828503,34.530163],[-79.658718,34.305608],[-80.074966,34.08653],[-80.244751,34.322039],[-80.288566,34.365854],[-80.288566,34.365854],[-79.866842,34.508255]]]}}, -{"type":"Feature","id":"45033","properties":{"name":"Dillon"},"geometry":{"type":"Polygon","coordinates":[[[-79.450595,34.623271],[-79.072686,34.300131],[-79.078163,34.294654],[-79.127455,34.256316],[-79.36844,34.300131],[-79.549179,34.228931],[-79.631334,34.300131],[-79.450595,34.623271]]]}}, -{"type":"Feature","id":"45035","properties":{"name":"Dorchester"},"geometry":{"type":"Polygon","coordinates":[[[-80.502167,33.33619],[-80.359767,33.259513],[-80.151643,33.024004],[-80.403582,32.859696],[-80.792445,33.182835],[-80.502167,33.33619]]]}}, -{"type":"Feature","id":"45037","properties":{"name":"Edgefield"},"geometry":{"type":"Polygon","coordinates":[[[-82.008326,33.960561],[-81.652325,33.812683],[-82.013803,33.53336],[-82.030233,33.544313],[-82.117864,33.599083],[-82.046664,33.955084],[-82.008326,33.960561]]]}}, -{"type":"Feature","id":"45039","properties":{"name":"Fairfield"},"geometry":{"type":"Polygon","coordinates":[[[-81.416816,34.573978],[-80.880076,34.541117],[-80.880076,34.458962],[-80.825307,34.26727],[-80.863645,34.261793],[-81.318231,34.239885],[-81.422293,34.491824],[-81.422293,34.573978],[-81.416816,34.573978]]]}}, -{"type":"Feature","id":"45041","properties":{"name":"Florence"},"geometry":{"type":"Polygon","coordinates":[[[-79.658718,34.305608],[-79.631334,34.300131],[-79.549179,34.228931],[-79.324625,33.80173],[-79.83398,33.883884],[-79.877796,33.883884],[-79.976381,33.94413],[-79.998289,34.048192],[-80.074966,34.08653],[-79.658718,34.305608]]]}}, -{"type":"Feature","id":"45043","properties":{"name":"Georgetown"},"geometry":{"type":"Polygon","coordinates":[[[-79.319148,33.779822],[-79.319148,33.779822],[-79.187701,33.703145],[-79.001485,33.571698],[-79.291763,33.111635],[-79.445118,33.215697],[-79.675149,33.303328],[-79.319148,33.779822]]]}}, -{"type":"Feature","id":"45045","properties":{"name":"Greenville"},"geometry":{"type":"Polygon","coordinates":[[[-82.353373,35.192872],[-82.216449,35.198349],[-82.145249,34.787579],[-82.315034,34.486347],[-82.484819,34.820441],[-82.621743,35.066903],[-82.764143,35.066903],[-82.572451,35.14358],[-82.353373,35.192872]]]}}, -{"type":"Feature","id":"45047","properties":{"name":"Greenwood"},"geometry":{"type":"Polygon","coordinates":[[[-82.243834,34.40967],[-81.942602,34.201546],[-81.871402,34.135823],[-82.008326,33.960561],[-82.046664,33.955084],[-82.325988,34.064623],[-82.243834,34.40967]]]}}, -{"type":"Feature","id":"45049","properties":{"name":"Hampton"},"geometry":{"type":"Polygon","coordinates":[[[-81.055338,33.002096],[-80.825307,32.706342],[-80.869122,32.662526],[-81.142969,32.657049],[-81.279893,32.558464],[-81.389431,32.596803],[-81.411339,32.74468],[-81.082723,33.024004],[-81.055338,33.002096]]]}}, -{"type":"Feature","id":"45051","properties":{"name":"Horry"},"geometry":{"type":"Polygon","coordinates":[[[-79.078163,34.294654],[-79.072686,34.300131],[-78.650961,33.94413],[-78.541422,33.851022],[-79.001485,33.571698],[-79.187701,33.703145],[-79.127455,34.256316],[-79.078163,34.294654]]]}}, -{"type":"Feature","id":"45053","properties":{"name":"Jasper"},"geometry":{"type":"Polygon","coordinates":[[[-81.142969,32.657049],[-80.869122,32.662526],[-80.880076,32.08197],[-80.885553,32.032678],[-81.148446,32.224371],[-81.279893,32.558464],[-81.142969,32.657049]]]}}, -{"type":"Feature","id":"45055","properties":{"name":"Kershaw"},"geometry":{"type":"Polygon","coordinates":[[[-80.387151,34.595886],[-80.288566,34.365854],[-80.288566,34.365854],[-80.480259,34.168685],[-80.617183,34.097484],[-80.825307,34.26727],[-80.880076,34.458962],[-80.409059,34.612317],[-80.387151,34.595886]]]}}, -{"type":"Feature","id":"45057","properties":{"name":"Lancaster"},"geometry":{"type":"Polygon","coordinates":[[[-80.907461,35.077857],[-80.907461,35.077857],[-80.841737,35.00118],[-80.562413,34.814964],[-80.409059,34.612317],[-80.880076,34.458962],[-80.880076,34.541117],[-80.896507,34.820441],[-80.907461,35.077857]]]}}, -{"type":"Feature","id":"45059","properties":{"name":"Laurens"},"geometry":{"type":"Polygon","coordinates":[[[-82.145249,34.787579],[-81.854971,34.595886],[-81.641371,34.53564],[-81.646848,34.519209],[-81.942602,34.201546],[-82.243834,34.40967],[-82.315034,34.486347],[-82.145249,34.787579]]]}}, -{"type":"Feature","id":"45061","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-80.244751,34.322039],[-80.074966,34.08653],[-79.998289,34.048192],[-80.480259,34.168685],[-80.288566,34.365854],[-80.244751,34.322039]]]}}, -{"type":"Feature","id":"45063","properties":{"name":"Lexington"},"geometry":{"type":"Polygon","coordinates":[[[-81.340139,34.196069],[-81.011523,33.878407],[-81.044384,33.796253],[-81.044384,33.708622],[-81.186785,33.653852],[-81.57017,33.878407],[-81.471585,34.075577],[-81.340139,34.196069]]]}}, -{"type":"Feature","id":"45065","properties":{"name":"McCormick"},"geometry":{"type":"Polygon","coordinates":[[[-82.594358,34.01533],[-82.325988,34.064623],[-82.046664,33.955084],[-82.117864,33.599083],[-82.216449,33.686714],[-82.566974,33.955084],[-82.594358,34.01533]]]}}, -{"type":"Feature","id":"45067","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-79.36844,34.300131],[-79.127455,34.256316],[-79.187701,33.703145],[-79.319148,33.779822],[-79.324625,33.80173],[-79.549179,34.228931],[-79.36844,34.300131]]]}}, -{"type":"Feature","id":"45069","properties":{"name":"Marlboro"},"geometry":{"type":"Polygon","coordinates":[[[-79.927088,34.80401],[-79.686103,34.80401],[-79.461548,34.628748],[-79.450595,34.623271],[-79.631334,34.300131],[-79.658718,34.305608],[-79.828503,34.530163],[-79.927088,34.80401]]]}}, -{"type":"Feature","id":"45071","properties":{"name":"Newberry"},"geometry":{"type":"Polygon","coordinates":[[[-81.646848,34.519209],[-81.641371,34.53564],[-81.422293,34.491824],[-81.318231,34.239885],[-81.340139,34.196069],[-81.471585,34.075577],[-81.739956,34.185115],[-81.871402,34.135823],[-81.942602,34.201546],[-81.646848,34.519209]]]}}, -{"type":"Feature","id":"45073","properties":{"name":"Oconee"},"geometry":{"type":"Polygon","coordinates":[[[-82.89559,35.055949],[-82.840821,34.623271],[-82.846298,34.617794],[-82.857251,34.60684],[-82.994175,34.48087],[-83.048944,34.497301],[-83.103714,34.53564],[-83.278976,34.645178],[-83.339222,34.688994],[-83.350176,34.716379],[-83.109191,35.00118],[-83.010606,35.028564],[-82.89559,35.055949]]]}}, -{"type":"Feature","id":"45075","properties":{"name":"Orangeburg"},"geometry":{"type":"Polygon","coordinates":[[[-81.044384,33.708622],[-80.49669,33.560744],[-80.222843,33.445728],[-80.359767,33.259513],[-80.502167,33.33619],[-80.792445,33.182835],[-80.797922,33.177358],[-81.10463,33.380005],[-81.225123,33.440252],[-81.373001,33.489544],[-81.186785,33.653852],[-81.044384,33.708622]]]}}, -{"type":"Feature","id":"45077","properties":{"name":"Pickens"},"geometry":{"type":"Polygon","coordinates":[[[-82.621743,35.066903],[-82.484819,34.820441],[-82.490296,34.820441],[-82.840821,34.623271],[-82.89559,35.055949],[-82.764143,35.066903],[-82.621743,35.066903]]]}}, -{"type":"Feature","id":"45079","properties":{"name":"Richland"},"geometry":{"type":"Polygon","coordinates":[[[-80.863645,34.261793],[-80.825307,34.26727],[-80.617183,34.097484],[-80.62266,33.741483],[-81.011523,33.878407],[-81.340139,34.196069],[-81.318231,34.239885],[-80.863645,34.261793]]]}}, -{"type":"Feature","id":"45081","properties":{"name":"Saluda"},"geometry":{"type":"Polygon","coordinates":[[[-81.739956,34.185115],[-81.471585,34.075577],[-81.57017,33.878407],[-81.652325,33.812683],[-82.008326,33.960561],[-81.871402,34.135823],[-81.739956,34.185115]]]}}, -{"type":"Feature","id":"45083","properties":{"name":"Spartanburg"},"geometry":{"type":"Polygon","coordinates":[[[-82.216449,35.198349],[-81.969987,35.187396],[-81.876879,35.181919],[-81.712571,34.913548],[-81.712571,34.913548],[-81.854971,34.595886],[-82.145249,34.787579],[-82.216449,35.198349]]]}}, -{"type":"Feature","id":"45085","properties":{"name":"Sumter"},"geometry":{"type":"Polygon","coordinates":[[[-80.480259,34.168685],[-79.998289,34.048192],[-79.976381,33.94413],[-80.332382,33.779822],[-80.535029,33.642898],[-80.62266,33.741483],[-80.617183,34.097484],[-80.480259,34.168685]]]}}, -{"type":"Feature","id":"45087","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-81.712571,34.913548],[-81.712571,34.913548],[-81.455155,34.836871],[-81.477062,34.820441],[-81.422293,34.573978],[-81.422293,34.491824],[-81.641371,34.53564],[-81.854971,34.595886],[-81.712571,34.913548]]]}}, -{"type":"Feature","id":"45089","properties":{"name":"Williamsburg"},"geometry":{"type":"Polygon","coordinates":[[[-79.83398,33.883884],[-79.324625,33.80173],[-79.319148,33.779822],[-79.319148,33.779822],[-79.675149,33.303328],[-80.053058,33.505975],[-80.10235,33.495021],[-79.877796,33.883884],[-79.83398,33.883884]]]}}, -{"type":"Feature","id":"45091","properties":{"name":"York"},"geometry":{"type":"Polygon","coordinates":[[[-81.367524,35.165488],[-81.329185,35.165488],[-81.044384,35.149057],[-80.907461,35.077857],[-80.907461,35.077857],[-80.896507,34.820441],[-81.28537,34.820441],[-81.477062,34.820441],[-81.455155,34.836871],[-81.367524,35.165488]]]}}, -{"type":"Feature","id":"46003","properties":{"name":"Aurora"},"geometry":{"type":"Polygon","coordinates":[[[-98.329608,43.939546],[-98.324131,43.851915],[-98.318654,43.501391],[-98.685609,43.501391],[-98.707517,43.501391],[-98.795148,43.501391],[-98.806102,43.934069],[-98.329608,43.939546]]]}}, -{"type":"Feature","id":"46005","properties":{"name":"Beadle"},"geometry":{"type":"Polygon","coordinates":[[[-98.088623,44.629641],[-97.979084,44.629641],[-97.853114,44.54201],[-97.853114,44.196962],[-98.209115,44.196962],[-98.329608,44.196962],[-98.691086,44.196962],[-98.70204,44.196962],[-98.707517,44.635118],[-98.088623,44.629641]]]}}, -{"type":"Feature","id":"46007","properties":{"name":"Bennett"},"geometry":{"type":"Polygon","coordinates":[[[-101.900573,43.391852],[-101.226909,43.391852],[-101.226909,42.997512],[-102.081312,42.997512],[-102.108697,43.391852],[-101.900573,43.391852]]]}}, -{"type":"Feature","id":"46009","properties":{"name":"Bon Homme"},"geometry":{"type":"Polygon","coordinates":[[[-97.754529,43.167298],[-97.639513,43.167298],[-97.634037,42.849635],[-98.154346,42.838681],[-98.077669,43.167298],[-97.754529,43.167298]]]}}, -{"type":"Feature","id":"46011","properties":{"name":"Brookings"},"geometry":{"type":"Polygon","coordinates":[[[-96.451017,44.54201],[-96.451017,44.196962],[-96.648187,44.196962],[-96.889173,44.196962],[-97.130158,44.196962],[-97.130158,44.54201],[-96.883696,44.54201],[-96.451017,44.54201]]]}}, -{"type":"Feature","id":"46013","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-98.723948,45.938629],[-98.006468,45.938629],[-97.979084,45.938629],[-97.979084,45.588105],[-97.979084,45.243058],[-98.532255,45.243058],[-98.718471,45.243058],[-98.723948,45.243058],[-98.723948,45.593582],[-98.723948,45.938629]]]}}, -{"type":"Feature","id":"46015","properties":{"name":"Brule"},"geometry":{"type":"Polygon","coordinates":[[[-98.806102,43.934069],[-98.795148,43.501391],[-99.299026,43.501391],[-99.353796,43.934069],[-98.926594,43.934069],[-98.806102,43.934069]]]}}, -{"type":"Feature","id":"46017","properties":{"name":"Buffalo"},"geometry":{"type":"Polygon","coordinates":[[[-98.926594,44.196962],[-98.926594,43.934069],[-99.353796,43.934069],[-99.57835,44.191485],[-99.299026,44.196962],[-98.926594,44.196962]]]}}, -{"type":"Feature","id":"46019","properties":{"name":"Butte"},"geometry":{"type":"Polygon","coordinates":[[[-104.042057,45.210196],[-102.957623,45.210196],[-102.957623,45.040411],[-102.963099,44.602256],[-103.565563,44.602256],[-103.812025,44.602256],[-104.058488,44.569394],[-104.058488,44.996596],[-104.042057,45.210196]]]}}, -{"type":"Feature","id":"46021","properties":{"name":"Campbell"},"geometry":{"type":"Polygon","coordinates":[[[-100.432753,45.944106],[-99.879582,45.944106],[-99.720751,45.938629],[-99.715274,45.593582],[-100.339645,45.593582],[-100.432753,45.593582],[-100.498476,45.944106],[-100.432753,45.944106]]]}}, -{"type":"Feature","id":"46023","properties":{"name":"Charles Mix"},"geometry":{"type":"Polygon","coordinates":[[[-99.299026,43.501391],[-98.795148,43.501391],[-98.707517,43.501391],[-98.11053,43.194682],[-98.077669,43.167298],[-98.154346,42.838681],[-98.3077,42.882497],[-98.499393,42.997512],[-99.299026,43.501391],[-99.299026,43.501391]]]}}, -{"type":"Feature","id":"46025","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-97.924314,45.155427],[-97.491636,45.14995],[-97.491636,44.804903],[-97.491636,44.54201],[-97.732621,44.54201],[-97.853114,44.54201],[-97.979084,44.629641],[-97.979084,45.155427],[-97.924314,45.155427]]]}}, -{"type":"Feature","id":"46027","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-96.807019,43.085144],[-96.807019,42.701758],[-97.015142,42.762004],[-97.16302,42.800343],[-97.157543,43.085144],[-96.922034,43.085144],[-96.807019,43.085144]]]}}, -{"type":"Feature","id":"46029","properties":{"name":"Codington"},"geometry":{"type":"Polygon","coordinates":[[[-97.23422,45.14995],[-97.228743,45.14995],[-96.883696,44.974688],[-96.883696,44.804903],[-97.491636,44.804903],[-97.491636,45.14995],[-97.23422,45.14995]]]}}, -{"type":"Feature","id":"46031","properties":{"name":"Corson"},"geometry":{"type":"Polygon","coordinates":[[[-101.999158,45.944106],[-100.50943,45.944106],[-100.498476,45.944106],[-100.432753,45.593582],[-100.339645,45.47309],[-100.772323,45.47309],[-101.467895,45.47309],[-101.714357,45.47309],[-101.999158,45.47309],[-101.999158,45.944106],[-101.999158,45.944106]]]}}, -{"type":"Feature","id":"46033","properties":{"name":"Custer"},"geometry":{"type":"Polygon","coordinates":[[[-103.417686,43.857392],[-102.809745,43.687607],[-103.001438,43.479483],[-103.937995,43.479483],[-104.053011,43.479483],[-104.053011,43.501391],[-104.053011,43.851915],[-103.417686,43.857392]]]}}, -{"type":"Feature","id":"46035","properties":{"name":"Davison"},"geometry":{"type":"Polygon","coordinates":[[[-98.203638,43.851915],[-97.96813,43.851915],[-97.962653,43.501391],[-98.116007,43.495914],[-98.318654,43.501391],[-98.324131,43.851915],[-98.203638,43.851915]]]}}, -{"type":"Feature","id":"46037","properties":{"name":"Day"},"geometry":{"type":"Polygon","coordinates":[[[-97.979084,45.588105],[-97.228743,45.560721],[-97.228743,45.297827],[-97.228743,45.14995],[-97.23422,45.14995],[-97.491636,45.14995],[-97.924314,45.155427],[-97.979084,45.155427],[-97.979084,45.243058],[-97.979084,45.588105]]]}}, -{"type":"Feature","id":"46039","properties":{"name":"Deuel"},"geometry":{"type":"Polygon","coordinates":[[[-96.451017,44.980165],[-96.451017,44.804903],[-96.451017,44.629641],[-96.451017,44.54201],[-96.883696,44.54201],[-96.883696,44.804903],[-96.883696,44.974688],[-96.451017,44.980165]]]}}, -{"type":"Feature","id":"46041","properties":{"name":"Dewey"},"geometry":{"type":"Polygon","coordinates":[[[-100.772323,45.47309],[-100.339645,45.47309],[-100.257491,45.248535],[-100.405368,44.898011],[-100.717554,44.772041],[-101.139278,44.744656],[-101.500756,44.991119],[-101.467895,45.47309],[-100.772323,45.47309]]]}}, -{"type":"Feature","id":"46043","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-98.685609,43.501391],[-98.318654,43.501391],[-98.116007,43.495914],[-98.11053,43.194682],[-98.707517,43.501391],[-98.685609,43.501391]]]}}, -{"type":"Feature","id":"46045","properties":{"name":"Edmunds"},"geometry":{"type":"Polygon","coordinates":[[[-99.709797,45.593582],[-98.723948,45.593582],[-98.723948,45.243058],[-99.572873,45.243058],[-99.709797,45.243058],[-99.709797,45.593582]]]}}, -{"type":"Feature","id":"46047","properties":{"name":"Fall River"},"geometry":{"type":"Polygon","coordinates":[[[-103.937995,43.479483],[-103.001438,43.479483],[-103.001438,43.002989],[-103.324578,43.002989],[-103.505317,43.002989],[-104.053011,43.002989],[-104.053011,43.479483],[-103.937995,43.479483]]]}}, -{"type":"Feature","id":"46049","properties":{"name":"Faulk"},"geometry":{"type":"Polygon","coordinates":[[[-99.572873,45.243058],[-98.723948,45.243058],[-98.718471,45.243058],[-98.718471,44.898011],[-99.30998,44.898011],[-99.572873,44.898011],[-99.572873,45.243058]]]}}, -{"type":"Feature","id":"46051","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-96.681049,45.325212],[-96.472925,45.325212],[-96.456494,45.303304],[-96.451017,45.297827],[-96.451017,45.270443],[-96.451017,44.980165],[-96.883696,44.974688],[-97.228743,45.14995],[-97.228743,45.297827],[-96.681049,45.325212]]]}}, -{"type":"Feature","id":"46053","properties":{"name":"Gregory"},"geometry":{"type":"Polygon","coordinates":[[[-99.534535,43.501391],[-99.299026,43.501391],[-98.499393,42.997512],[-99.255211,42.997512],[-99.534535,42.997512],[-99.534535,43.501391]]]}}, -{"type":"Feature","id":"46055","properties":{"name":"Haakon"},"geometry":{"type":"Polygon","coordinates":[[[-101.380264,44.657025],[-101.139278,44.744656],[-101.04617,44.169578],[-101.062601,43.994316],[-101.407648,43.994316],[-102.004635,43.994316],[-101.999158,44.509148],[-101.999158,44.509148],[-101.380264,44.657025]]]}}, -{"type":"Feature","id":"46057","properties":{"name":"Hamlin"},"geometry":{"type":"Polygon","coordinates":[[[-96.883696,44.804903],[-96.883696,44.54201],[-97.130158,44.54201],[-97.491636,44.54201],[-97.491636,44.804903],[-96.883696,44.804903]]]}}, -{"type":"Feature","id":"46059","properties":{"name":"Hand"},"geometry":{"type":"Polygon","coordinates":[[[-99.30998,44.898011],[-98.718471,44.898011],[-98.707517,44.635118],[-98.70204,44.196962],[-98.926594,44.196962],[-99.299026,44.196962],[-99.30998,44.898011]]]}}, -{"type":"Feature","id":"46061","properties":{"name":"Hanson"},"geometry":{"type":"Polygon","coordinates":[[[-97.853114,43.851915],[-97.606652,43.846438],[-97.606652,43.501391],[-97.962653,43.501391],[-97.96813,43.851915],[-97.853114,43.851915]]]}}, -{"type":"Feature","id":"46063","properties":{"name":"Harding"},"geometry":{"type":"Polygon","coordinates":[[[-104.047534,45.944106],[-102.995961,45.944106],[-102.941192,45.944106],[-102.957623,45.210196],[-104.042057,45.210196],[-104.042057,45.88386],[-104.047534,45.944106]]]}}, -{"type":"Feature","id":"46065","properties":{"name":"Hughes"},"geometry":{"type":"Polygon","coordinates":[[[-99.857674,44.547487],[-99.676935,44.547487],[-99.665981,44.21887],[-99.939828,44.196962],[-100.525861,44.547487],[-99.857674,44.547487]]]}}, -{"type":"Feature","id":"46067","properties":{"name":"Hutchinson"},"geometry":{"type":"Polygon","coordinates":[[[-97.606652,43.501391],[-97.404005,43.501391],[-97.398528,43.167298],[-97.639513,43.167298],[-97.754529,43.167298],[-98.077669,43.167298],[-98.11053,43.194682],[-98.116007,43.495914],[-97.962653,43.501391],[-97.606652,43.501391]]]}}, -{"type":"Feature","id":"46069","properties":{"name":"Hyde"},"geometry":{"type":"Polygon","coordinates":[[[-99.572873,44.898011],[-99.30998,44.898011],[-99.299026,44.196962],[-99.57835,44.191485],[-99.665981,44.21887],[-99.676935,44.547487],[-99.676935,44.898011],[-99.572873,44.898011]]]}}, -{"type":"Feature","id":"46071","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-101.407648,43.994316],[-101.062601,43.994316],[-101.062601,43.840961],[-101.226909,43.391852],[-101.900573,43.391852],[-102.108697,43.391852],[-102.141558,43.698561],[-102.004635,43.994316],[-101.407648,43.994316]]]}}, -{"type":"Feature","id":"46073","properties":{"name":"Jerauld"},"geometry":{"type":"Polygon","coordinates":[[[-98.691086,44.196962],[-98.329608,44.196962],[-98.329608,43.939546],[-98.806102,43.934069],[-98.926594,43.934069],[-98.926594,44.196962],[-98.70204,44.196962],[-98.691086,44.196962]]]}}, -{"type":"Feature","id":"46075","properties":{"name":"Jones"},"geometry":{"type":"Polygon","coordinates":[[[-101.013309,44.169578],[-100.36703,44.169578],[-100.339645,43.714992],[-101.062601,43.840961],[-101.062601,43.994316],[-101.04617,44.169578],[-101.013309,44.169578]]]}}, -{"type":"Feature","id":"46077","properties":{"name":"Kingsbury"},"geometry":{"type":"Polygon","coordinates":[[[-97.732621,44.54201],[-97.491636,44.54201],[-97.130158,44.54201],[-97.130158,44.196962],[-97.217789,44.196962],[-97.371143,44.196962],[-97.727145,44.196962],[-97.847637,44.196962],[-97.853114,44.196962],[-97.853114,44.54201],[-97.732621,44.54201]]]}}, -{"type":"Feature","id":"46079","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-97.217789,44.196962],[-97.130158,44.196962],[-96.889173,44.196962],[-96.889173,43.846438],[-97.130158,43.846438],[-97.371143,43.846438],[-97.371143,44.196962],[-97.217789,44.196962]]]}}, -{"type":"Feature","id":"46081","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-103.812025,44.602256],[-103.565563,44.602256],[-103.450547,44.142193],[-104.053011,44.142193],[-104.053011,44.180532],[-104.058488,44.569394],[-103.812025,44.602256]]]}}, -{"type":"Feature","id":"46083","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-96.779634,43.501391],[-96.598895,43.501391],[-96.555079,43.260406],[-96.456494,43.085144],[-96.626279,43.085144],[-96.807019,43.085144],[-96.922034,43.085144],[-96.922034,43.501391],[-96.779634,43.501391]]]}}, -{"type":"Feature","id":"46085","properties":{"name":"Lyman"},"geometry":{"type":"Polygon","coordinates":[[[-100.224629,44.196962],[-99.939828,44.196962],[-99.665981,44.21887],[-99.57835,44.191485],[-99.353796,43.934069],[-99.299026,43.501391],[-99.299026,43.501391],[-99.534535,43.501391],[-99.665981,43.75333],[-100.230106,43.714992],[-100.339645,43.714992],[-100.36703,44.169578],[-100.224629,44.196962]]]}}, -{"type":"Feature","id":"46087","properties":{"name":"McCook"},"geometry":{"type":"Polygon","coordinates":[[[-97.491636,43.846438],[-97.371143,43.846438],[-97.130158,43.846438],[-97.130158,43.501391],[-97.404005,43.501391],[-97.606652,43.501391],[-97.606652,43.846438],[-97.491636,43.846438]]]}}, -{"type":"Feature","id":"46089","properties":{"name":"McPherson"},"geometry":{"type":"Polygon","coordinates":[[[-99.720751,45.938629],[-99.003272,45.938629],[-98.723948,45.938629],[-98.723948,45.593582],[-99.709797,45.593582],[-99.715274,45.593582],[-99.720751,45.938629]]]}}, -{"type":"Feature","id":"46091","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-97.853114,45.933153],[-97.228743,45.933153],[-97.228743,45.560721],[-97.979084,45.588105],[-97.979084,45.938629],[-97.853114,45.933153]]]}}, -{"type":"Feature","id":"46093","properties":{"name":"Meade"},"geometry":{"type":"Polygon","coordinates":[[[-102.042974,45.040411],[-101.999158,45.040411],[-101.999158,44.509148],[-101.999158,44.509148],[-102.119651,44.437948],[-102.388021,44.142193],[-103.450547,44.142193],[-103.565563,44.602256],[-102.963099,44.602256],[-102.957623,45.040411],[-102.042974,45.040411]]]}}, -{"type":"Feature","id":"46095","properties":{"name":"Mellette"},"geometry":{"type":"Polygon","coordinates":[[[-101.062601,43.840961],[-100.339645,43.714992],[-100.230106,43.714992],[-100.213675,43.391852],[-100.235583,43.391852],[-101.226909,43.391852],[-101.062601,43.840961]]]}}, -{"type":"Feature","id":"46097","properties":{"name":"Miner"},"geometry":{"type":"Polygon","coordinates":[[[-97.727145,44.196962],[-97.371143,44.196962],[-97.371143,43.846438],[-97.491636,43.846438],[-97.606652,43.846438],[-97.853114,43.851915],[-97.847637,44.196962],[-97.727145,44.196962]]]}}, -{"type":"Feature","id":"46099","properties":{"name":"Minnehaha"},"geometry":{"type":"Polygon","coordinates":[[[-96.489356,43.846438],[-96.451017,43.851915],[-96.451017,43.501391],[-96.598895,43.501391],[-96.779634,43.501391],[-96.922034,43.501391],[-97.130158,43.501391],[-97.130158,43.846438],[-96.889173,43.846438],[-96.489356,43.846438]]]}}, -{"type":"Feature","id":"46101","properties":{"name":"Moody"},"geometry":{"type":"Polygon","coordinates":[[[-96.648187,44.196962],[-96.451017,44.196962],[-96.451017,43.851915],[-96.489356,43.846438],[-96.889173,43.846438],[-96.889173,44.196962],[-96.648187,44.196962]]]}}, -{"type":"Feature","id":"46103","properties":{"name":"Pennington"},"geometry":{"type":"Polygon","coordinates":[[[-102.119651,44.437948],[-101.999158,44.509148],[-102.004635,43.994316],[-102.141558,43.698561],[-102.256574,43.687607],[-102.809745,43.687607],[-103.417686,43.857392],[-104.053011,43.851915],[-104.053011,44.142193],[-103.450547,44.142193],[-102.388021,44.142193],[-102.119651,44.437948]]]}}, -{"type":"Feature","id":"46105","properties":{"name":"Perkins"},"geometry":{"type":"Polygon","coordinates":[[[-102.623529,45.944106],[-101.999158,45.944106],[-101.999158,45.47309],[-101.999158,45.040411],[-102.042974,45.040411],[-102.957623,45.040411],[-102.957623,45.210196],[-102.941192,45.944106],[-102.623529,45.944106]]]}}, -{"type":"Feature","id":"46107","properties":{"name":"Potter"},"geometry":{"type":"Polygon","coordinates":[[[-100.257491,45.248535],[-99.709797,45.243058],[-99.572873,45.243058],[-99.572873,44.898011],[-99.676935,44.898011],[-100.405368,44.898011],[-100.257491,45.248535]]]}}, -{"type":"Feature","id":"46109","properties":{"name":"Roberts"},"geometry":{"type":"Polygon","coordinates":[[[-96.735818,45.933153],[-96.560556,45.933153],[-96.834403,45.588105],[-96.472925,45.325212],[-96.681049,45.325212],[-97.228743,45.297827],[-97.228743,45.560721],[-97.228743,45.933153],[-96.735818,45.933153]]]}}, -{"type":"Feature","id":"46111","properties":{"name":"Sanborn"},"geometry":{"type":"Polygon","coordinates":[[[-98.209115,44.196962],[-97.853114,44.196962],[-97.847637,44.196962],[-97.853114,43.851915],[-97.96813,43.851915],[-98.203638,43.851915],[-98.324131,43.851915],[-98.329608,43.939546],[-98.329608,44.196962],[-98.209115,44.196962]]]}}, -{"type":"Feature","id":"46113","properties":{"name":"Shannon"},"geometry":{"type":"Polygon","coordinates":[[[-102.256574,43.687607],[-102.141558,43.698561],[-102.108697,43.391852],[-102.081312,42.997512],[-102.081312,42.997512],[-102.793314,42.997512],[-103.001438,43.002989],[-103.001438,43.479483],[-102.809745,43.687607],[-102.256574,43.687607]]]}}, -{"type":"Feature","id":"46115","properties":{"name":"Spink"},"geometry":{"type":"Polygon","coordinates":[[[-98.532255,45.243058],[-97.979084,45.243058],[-97.979084,45.155427],[-97.979084,44.629641],[-98.088623,44.629641],[-98.707517,44.635118],[-98.718471,44.898011],[-98.718471,45.243058],[-98.532255,45.243058]]]}}, -{"type":"Feature","id":"46117","properties":{"name":"Stanley"},"geometry":{"type":"Polygon","coordinates":[[[-100.717554,44.772041],[-100.525861,44.547487],[-99.939828,44.196962],[-100.224629,44.196962],[-100.36703,44.169578],[-101.013309,44.169578],[-101.04617,44.169578],[-101.139278,44.744656],[-100.717554,44.772041]]]}}, -{"type":"Feature","id":"46119","properties":{"name":"Sully"},"geometry":{"type":"Polygon","coordinates":[[[-100.405368,44.898011],[-99.676935,44.898011],[-99.676935,44.547487],[-99.857674,44.547487],[-100.525861,44.547487],[-100.717554,44.772041],[-100.405368,44.898011]]]}}, -{"type":"Feature","id":"46121","properties":{"name":"Todd"},"geometry":{"type":"Polygon","coordinates":[[[-100.235583,43.391852],[-100.213675,43.391852],[-100.197245,42.997512],[-101.226909,42.997512],[-101.226909,43.391852],[-100.235583,43.391852]]]}}, -{"type":"Feature","id":"46123","properties":{"name":"Tripp"},"geometry":{"type":"Polygon","coordinates":[[[-99.665981,43.75333],[-99.534535,43.501391],[-99.534535,42.997512],[-100.126044,42.997512],[-100.197245,42.997512],[-100.213675,43.391852],[-100.230106,43.714992],[-99.665981,43.75333]]]}}, -{"type":"Feature","id":"46125","properties":{"name":"Turner"},"geometry":{"type":"Polygon","coordinates":[[[-96.922034,43.501391],[-96.922034,43.085144],[-97.157543,43.085144],[-97.343759,43.167298],[-97.398528,43.167298],[-97.404005,43.501391],[-97.130158,43.501391],[-96.922034,43.501391]]]}}, -{"type":"Feature","id":"46127","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-96.626279,43.085144],[-96.456494,43.085144],[-96.538648,42.909881],[-96.50031,42.559357],[-96.44554,42.488157],[-96.631756,42.526496],[-96.807019,42.701758],[-96.807019,43.085144],[-96.626279,43.085144]]]}}, -{"type":"Feature","id":"46129","properties":{"name":"Walworth"},"geometry":{"type":"Polygon","coordinates":[[[-100.339645,45.593582],[-99.715274,45.593582],[-99.709797,45.593582],[-99.709797,45.243058],[-100.257491,45.248535],[-100.339645,45.47309],[-100.432753,45.593582],[-100.339645,45.593582]]]}}, -{"type":"Feature","id":"46135","properties":{"name":"Yankton"},"geometry":{"type":"Polygon","coordinates":[[[-97.343759,43.167298],[-97.157543,43.085144],[-97.16302,42.800343],[-97.486159,42.849635],[-97.634037,42.849635],[-97.639513,43.167298],[-97.398528,43.167298],[-97.343759,43.167298]]]}}, -{"type":"Feature","id":"46137","properties":{"name":"Ziebach"},"geometry":{"type":"Polygon","coordinates":[[[-101.714357,45.47309],[-101.467895,45.47309],[-101.500756,44.991119],[-101.139278,44.744656],[-101.380264,44.657025],[-101.999158,44.509148],[-101.999158,45.040411],[-101.999158,45.47309],[-101.714357,45.47309]]]}}, -{"type":"Feature","id":"47001","properties":{"name":"Anderson"},"geometry":{"type":"Polygon","coordinates":[[[-84.001932,36.27183],[-83.941686,36.184199],[-84.270302,35.910352],[-84.341502,36.047275],[-84.440087,36.162291],[-84.374364,36.21706],[-84.001932,36.27183]]]}}, -{"type":"Feature","id":"47003","properties":{"name":"Bedford"},"geometry":{"type":"Polygon","coordinates":[[[-86.521325,35.691274],[-86.247477,35.631028],[-86.258431,35.41195],[-86.526801,35.357181],[-86.598002,35.362658],[-86.641817,35.685797],[-86.521325,35.691274]]]}}, -{"type":"Feature","id":"47005","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-87.989145,36.359461],[-87.983668,36.353984],[-87.950806,36.244445],[-87.96176,35.839151],[-87.972714,35.817244],[-88.175361,35.844628],[-88.213699,36.118475],[-87.989145,36.359461]]]}}, -{"type":"Feature","id":"47007","properties":{"name":"Bledsoe"},"geometry":{"type":"Polygon","coordinates":[[[-85.256151,35.767951],[-85.256151,35.767951],[-84.916581,35.762474],[-85.135659,35.455766],[-85.22329,35.351704],[-85.425936,35.565304],[-85.256151,35.767951]]]}}, -{"type":"Feature","id":"47009","properties":{"name":"Blount"},"geometry":{"type":"Polygon","coordinates":[[[-83.793808,35.888444],[-83.662362,35.570781],[-83.952639,35.461243],[-83.963593,35.461243],[-84.188148,35.60912],[-84.16624,35.80629],[-83.793808,35.888444]]]}}, -{"type":"Feature","id":"47011","properties":{"name":"Bradley"},"geometry":{"type":"Polygon","coordinates":[[[-84.872765,35.357181],[-84.861812,35.351704],[-84.70298,35.242165],[-84.774181,34.990226],[-84.812519,34.990226],[-84.976827,34.990226],[-84.943966,35.28598],[-84.872765,35.357181]]]}}, -{"type":"Feature","id":"47013","properties":{"name":"Campbell"},"geometry":{"type":"Polygon","coordinates":[[[-84.226487,36.589492],[-83.985501,36.589492],[-83.903347,36.419707],[-84.001932,36.27183],[-84.374364,36.21706],[-84.259348,36.589492],[-84.226487,36.589492]]]}}, -{"type":"Feature","id":"47015","properties":{"name":"Cannon"},"geometry":{"type":"Polygon","coordinates":[[[-86.017446,35.959644],[-85.885999,35.839151],[-85.984584,35.658412],[-86.209139,35.702228],[-86.15437,35.954167],[-86.017446,35.959644]]]}}, -{"type":"Feature","id":"47017","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-88.531362,36.151337],[-88.213699,36.118475],[-88.175361,35.844628],[-88.180837,35.817244],[-88.514931,35.822721],[-88.608039,35.789859],[-88.706624,35.789859],[-88.690193,36.063706],[-88.531362,36.151337]]]}}, -{"type":"Feature","id":"47019","properties":{"name":"Carter"},"geometry":{"type":"Polygon","coordinates":[[[-81.986418,36.507338],[-81.931648,36.266353],[-82.079526,36.107521],[-82.221926,36.156814],[-82.320511,36.260876],[-82.342419,36.255399],[-82.298603,36.397799],[-81.986418,36.507338]]]}}, -{"type":"Feature","id":"47021","properties":{"name":"Cheatham"},"geometry":{"type":"Polygon","coordinates":[[[-87.118311,36.458046],[-86.915664,36.381369],[-87.052588,36.047275],[-87.184034,36.047275],[-87.288096,36.321122],[-87.118311,36.458046]]]}}, -{"type":"Feature","id":"47023","properties":{"name":"Chester"},"geometry":{"type":"Polygon","coordinates":[[[-88.701147,35.477673],[-88.613516,35.587212],[-88.361576,35.417427],[-88.361576,35.379088],[-88.378007,35.373611],[-88.783301,35.247642],[-88.843547,35.428381],[-88.701147,35.477673]]]}}, -{"type":"Feature","id":"47025","properties":{"name":"Claiborne"},"geometry":{"type":"Polygon","coordinates":[[[-83.673316,36.600446],[-83.470669,36.594969],[-83.388515,36.41423],[-83.667839,36.34303],[-83.903347,36.419707],[-83.985501,36.589492],[-83.930732,36.589492],[-83.673316,36.600446]]]}}, -{"type":"Feature","id":"47027","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-85.278059,36.627831],[-85.283536,36.529246],[-85.497137,36.403276],[-85.814799,36.501861],[-85.787415,36.622354],[-85.43689,36.616877],[-85.29449,36.627831],[-85.278059,36.627831]]]}}, -{"type":"Feature","id":"47029","properties":{"name":"Cocke"},"geometry":{"type":"Polygon","coordinates":[[[-83.16396,36.178722],[-82.901067,35.943213],[-82.961313,35.789859],[-83.257068,35.713182],[-83.311837,35.893921],[-83.23516,36.085614],[-83.16396,36.178722]]]}}, -{"type":"Feature","id":"47031","properties":{"name":"Coffee"},"geometry":{"type":"Polygon","coordinates":[[[-86.209139,35.702228],[-85.984584,35.658412],[-85.875046,35.521489],[-85.913384,35.291457],[-86.214616,35.346227],[-86.263908,35.335273],[-86.258431,35.41195],[-86.258431,35.41195],[-86.247477,35.631028],[-86.209139,35.702228]]]}}, -{"type":"Feature","id":"47033","properties":{"name":"Crockett"},"geometry":{"type":"Polygon","coordinates":[[[-89.188594,35.997983],[-88.914747,35.795336],[-89.068102,35.691274],[-89.341949,35.789859],[-89.35838,35.817244],[-89.341949,35.882967],[-89.188594,35.997983],[-89.188594,35.997983]]]}}, -{"type":"Feature","id":"47035","properties":{"name":"Cumberland"},"geometry":{"type":"Polygon","coordinates":[[[-84.987781,36.162291],[-84.905627,36.156814],[-84.681073,35.910352],[-84.779657,35.822721],[-84.916581,35.762474],[-85.256151,35.767951],[-85.256151,35.767951],[-85.272582,35.789859],[-85.267105,35.795336],[-85.261628,35.981552],[-85.102797,36.140383],[-84.987781,36.162291]]]}}, -{"type":"Feature","id":"47037","properties":{"name":"Davidson"},"geometry":{"type":"Polygon","coordinates":[[[-86.76231,36.403276],[-86.756833,36.403276],[-86.592525,36.244445],[-86.515848,36.102045],[-86.619909,35.970598],[-86.921141,36.052752],[-87.052588,36.047275],[-86.915664,36.381369],[-86.76231,36.403276]]]}}, -{"type":"Feature","id":"47039","properties":{"name":"Decatur"},"geometry":{"type":"Polygon","coordinates":[[[-88.175361,35.844628],[-87.972714,35.817244],[-88.005575,35.422904],[-88.022006,35.390042],[-88.241084,35.422904],[-88.180837,35.817244],[-88.175361,35.844628]]]}}, -{"type":"Feature","id":"47041","properties":{"name":"DeKalb"},"geometry":{"type":"Polygon","coordinates":[[[-85.809322,36.129429],[-85.645014,36.014414],[-85.683353,35.833674],[-85.885999,35.839151],[-86.017446,35.959644],[-86.061262,36.085614],[-85.809322,36.129429]]]}}, -{"type":"Feature","id":"47043","properties":{"name":"Dickson"},"geometry":{"type":"Polygon","coordinates":[[[-87.512651,36.332076],[-87.288096,36.321122],[-87.184034,36.047275],[-87.205942,35.959644],[-87.512651,35.992506],[-87.534558,35.992506],[-87.56742,36.178722],[-87.512651,36.332076]]]}}, -{"type":"Feature","id":"47045","properties":{"name":"Dyer"},"geometry":{"type":"Polygon","coordinates":[[[-89.265272,36.206106],[-89.155733,36.206106],[-89.188594,35.997983],[-89.341949,35.882967],[-89.489826,35.94869],[-89.643181,35.904875],[-89.730812,35.997983],[-89.62675,36.184199],[-89.484349,36.211583],[-89.265272,36.206106]]]}}, -{"type":"Feature","id":"47047","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-89.550073,35.400996],[-89.473395,35.400996],[-89.183118,35.395519],[-89.199548,34.995703],[-89.352903,34.995703],[-89.643181,34.995703],[-89.632227,35.373611],[-89.550073,35.400996]]]}}, -{"type":"Feature","id":"47049","properties":{"name":"Fentress"},"geometry":{"type":"Polygon","coordinates":[[[-85.009689,36.567584],[-84.730365,36.523769],[-84.70298,36.370415],[-84.724888,36.375892],[-84.905627,36.156814],[-84.987781,36.162291],[-85.102797,36.140383],[-85.119228,36.14586],[-85.119228,36.408753],[-85.009689,36.567584]]]}}, -{"type":"Feature","id":"47051","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-86.214616,35.346227],[-85.913384,35.291457],[-85.875046,35.225734],[-85.864092,34.990226],[-86.313201,34.990226],[-86.318678,34.990226],[-86.318678,35.127149],[-86.263908,35.335273],[-86.214616,35.346227]]]}}, -{"type":"Feature","id":"47053","properties":{"name":"Gibson"},"geometry":{"type":"Polygon","coordinates":[[[-89.155733,36.206106],[-88.958563,36.222537],[-88.690193,36.063706],[-88.706624,35.789859],[-88.914747,35.795336],[-89.188594,35.997983],[-89.188594,35.997983],[-89.155733,36.206106]]]}}, -{"type":"Feature","id":"47055","properties":{"name":"Giles"},"geometry":{"type":"Polygon","coordinates":[[[-87.129265,35.455766],[-86.95948,35.417427],[-86.828033,35.264073],[-86.838987,34.990226],[-87.211419,35.00118],[-87.222373,35.00118],[-87.205942,35.433858],[-87.129265,35.455766]]]}}, -{"type":"Feature","id":"47057","properties":{"name":"Grainger"},"geometry":{"type":"Polygon","coordinates":[[[-83.278976,36.392322],[-83.257068,36.288261],[-83.465192,36.173245],[-83.602115,36.151337],[-83.667839,36.080137],[-83.733562,36.162291],[-83.667839,36.34303],[-83.388515,36.41423],[-83.278976,36.392322]]]}}, -{"type":"Feature","id":"47059","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-82.632697,36.419707],[-82.594358,36.096568],[-82.605312,36.041798],[-82.786051,35.987029],[-82.901067,35.943213],[-83.16396,36.178722],[-83.081806,36.244445],[-82.703897,36.408753],[-82.632697,36.419707]]]}}, -{"type":"Feature","id":"47061","properties":{"name":"Grundy"},"geometry":{"type":"Polygon","coordinates":[[[-85.590245,35.521489],[-85.557383,35.318842],[-85.601199,35.307888],[-85.875046,35.225734],[-85.913384,35.291457],[-85.875046,35.521489],[-85.606675,35.532443],[-85.590245,35.521489]]]}}, -{"type":"Feature","id":"47063","properties":{"name":"Hamblen"},"geometry":{"type":"Polygon","coordinates":[[[-83.158483,36.332076],[-83.081806,36.244445],[-83.16396,36.178722],[-83.23516,36.085614],[-83.465192,36.173245],[-83.257068,36.288261],[-83.158483,36.332076]]]}}, -{"type":"Feature","id":"47065","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-85.130182,35.455766],[-85.015166,35.41195],[-84.943966,35.28598],[-84.976827,34.990226],[-84.982304,34.990226],[-85.267105,34.984749],[-85.272582,34.984749],[-85.36569,34.984749],[-85.475229,34.984749],[-85.387598,35.149057],[-85.22329,35.351704],[-85.135659,35.455766],[-85.130182,35.455766]]]}}, -{"type":"Feature","id":"47067","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-82.983221,36.594969],[-82.829867,36.594969],[-83.278976,36.392322],[-83.388515,36.41423],[-83.470669,36.594969],[-82.983221,36.594969]]]}}, -{"type":"Feature","id":"47069","properties":{"name":"Hardeman"},"geometry":{"type":"Polygon","coordinates":[[[-89.150256,35.433858],[-89.079056,35.433858],[-88.843547,35.428381],[-88.783301,35.247642],[-88.788778,34.995703],[-88.821639,34.995703],[-89.018809,34.995703],[-89.199548,34.995703],[-89.183118,35.395519],[-89.150256,35.433858]]]}}, -{"type":"Feature","id":"47071","properties":{"name":"Hardin"},"geometry":{"type":"Polygon","coordinates":[[[-88.361576,35.417427],[-88.241084,35.422904],[-88.022006,35.390042],[-87.983668,35.006656],[-88.202745,34.995703],[-88.252038,34.995703],[-88.361576,34.995703],[-88.378007,34.995703],[-88.361576,35.379088],[-88.361576,35.417427]]]}}, -{"type":"Feature","id":"47073","properties":{"name":"Hawkins"},"geometry":{"type":"Polygon","coordinates":[[[-82.654605,36.594969],[-82.610789,36.594969],[-82.681989,36.430661],[-82.703897,36.408753],[-83.081806,36.244445],[-83.158483,36.332076],[-83.257068,36.288261],[-83.278976,36.392322],[-82.829867,36.594969],[-82.654605,36.594969]]]}}, -{"type":"Feature","id":"47075","properties":{"name":"Haywood"},"geometry":{"type":"Polygon","coordinates":[[[-89.341949,35.789859],[-89.068102,35.691274],[-89.079056,35.433858],[-89.150256,35.433858],[-89.183118,35.395519],[-89.473395,35.400996],[-89.50078,35.581735],[-89.35838,35.817244],[-89.341949,35.789859]]]}}, -{"type":"Feature","id":"47077","properties":{"name":"Henderson"},"geometry":{"type":"Polygon","coordinates":[[[-88.514931,35.822721],[-88.180837,35.817244],[-88.241084,35.422904],[-88.361576,35.417427],[-88.613516,35.587212],[-88.608039,35.789859],[-88.514931,35.822721]]]}}, -{"type":"Feature","id":"47079","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-88.514931,36.501861],[-88.487546,36.501861],[-88.054868,36.496384],[-87.989145,36.359461],[-88.213699,36.118475],[-88.531362,36.151337],[-88.514931,36.501861]]]}}, -{"type":"Feature","id":"47081","properties":{"name":"Hickman"},"geometry":{"type":"Polygon","coordinates":[[[-87.512651,35.992506],[-87.205942,35.959644],[-87.216896,35.850105],[-87.337389,35.658412],[-87.660528,35.60912],[-87.720774,35.795336],[-87.715298,35.839151],[-87.534558,35.992506],[-87.512651,35.992506]]]}}, -{"type":"Feature","id":"47083","properties":{"name":"Houston"},"geometry":{"type":"Polygon","coordinates":[[[-87.753636,36.34303],[-87.594805,36.364938],[-87.512651,36.332076],[-87.56742,36.178722],[-87.879606,36.233491],[-87.950806,36.244445],[-87.983668,36.353984],[-87.753636,36.34303]]]}}, -{"type":"Feature","id":"47085","properties":{"name":"Humphreys"},"geometry":{"type":"Polygon","coordinates":[[[-87.879606,36.233491],[-87.56742,36.178722],[-87.534558,35.992506],[-87.715298,35.839151],[-87.96176,35.839151],[-87.950806,36.244445],[-87.879606,36.233491]]]}}, -{"type":"Feature","id":"47087","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-85.814799,36.501861],[-85.497137,36.403276],[-85.497137,36.304691],[-85.497137,36.299214],[-85.781938,36.238968],[-85.825753,36.41423],[-85.814799,36.501861]]]}}, -{"type":"Feature","id":"47089","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-83.602115,36.151337],[-83.465192,36.173245],[-83.23516,36.085614],[-83.311837,35.893921],[-83.673316,36.036321],[-83.667839,36.080137],[-83.602115,36.151337]]]}}, -{"type":"Feature","id":"47091","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-81.827587,36.616877],[-81.646848,36.6114],[-81.679709,36.589492],[-81.734479,36.392322],[-81.920695,36.288261],[-81.931648,36.266353],[-81.986418,36.507338],[-81.827587,36.616877]]]}}, -{"type":"Feature","id":"47093","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-83.925255,36.173245],[-83.733562,36.162291],[-83.667839,36.080137],[-83.673316,36.036321],[-83.678792,36.030844],[-83.793808,35.888444],[-84.16624,35.80629],[-84.264825,35.899398],[-84.270302,35.910352],[-83.941686,36.184199],[-83.925255,36.173245]]]}}, -{"type":"Feature","id":"47095","properties":{"name":"Lake"},"geometry":{"type":"Polygon","coordinates":[[[-89.347426,36.501861],[-89.484349,36.211583],[-89.62675,36.184199],[-89.544596,36.337553],[-89.539119,36.496384],[-89.484349,36.496384],[-89.418626,36.496384],[-89.347426,36.501861]]]}}, -{"type":"Feature","id":"47097","properties":{"name":"Lauderdale"},"geometry":{"type":"Polygon","coordinates":[[[-89.489826,35.94869],[-89.341949,35.882967],[-89.35838,35.817244],[-89.50078,35.581735],[-89.643181,35.647459],[-89.911551,35.53792],[-89.643181,35.904875],[-89.489826,35.94869]]]}}, -{"type":"Feature","id":"47099","properties":{"name":"Lawrence"},"geometry":{"type":"Polygon","coordinates":[[[-87.435974,35.455766],[-87.293573,35.444812],[-87.205942,35.433858],[-87.222373,35.00118],[-87.605759,35.00118],[-87.572897,35.400996],[-87.435974,35.455766]]]}}, -{"type":"Feature","id":"47101","properties":{"name":"Lewis"},"geometry":{"type":"Polygon","coordinates":[[[-87.337389,35.658412],[-87.293573,35.444812],[-87.435974,35.455766],[-87.572897,35.400996],[-87.715298,35.48315],[-87.660528,35.60912],[-87.337389,35.658412]]]}}, -{"type":"Feature","id":"47103","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-86.598002,35.362658],[-86.526801,35.357181],[-86.318678,35.127149],[-86.318678,34.990226],[-86.784218,34.990226],[-86.838987,34.990226],[-86.828033,35.264073],[-86.598002,35.362658]]]}}, -{"type":"Feature","id":"47105","properties":{"name":"Loudon"},"geometry":{"type":"Polygon","coordinates":[[[-84.264825,35.899398],[-84.16624,35.80629],[-84.188148,35.60912],[-84.43461,35.669366],[-84.527718,35.625551],[-84.582488,35.641982],[-84.264825,35.899398]]]}}, -{"type":"Feature","id":"47107","properties":{"name":"McMinn"},"geometry":{"type":"Polygon","coordinates":[[[-84.582488,35.641982],[-84.527718,35.625551],[-84.522241,35.620074],[-84.522241,35.60912],[-84.494857,35.28598],[-84.686549,35.253119],[-84.70298,35.242165],[-84.861812,35.351704],[-84.620826,35.641982],[-84.582488,35.641982]]]}}, -{"type":"Feature","id":"47109","properties":{"name":"McNairy"},"geometry":{"type":"Polygon","coordinates":[[[-88.378007,35.373611],[-88.361576,35.379088],[-88.378007,34.995703],[-88.471115,34.995703],[-88.788778,34.995703],[-88.783301,35.247642],[-88.378007,35.373611]]]}}, -{"type":"Feature","id":"47111","properties":{"name":"Macon"},"geometry":{"type":"Polygon","coordinates":[[[-86.203662,36.638785],[-85.979107,36.627831],[-85.787415,36.622354],[-85.814799,36.501861],[-85.825753,36.41423],[-85.979107,36.425184],[-86.231047,36.48543],[-86.203662,36.638785]]]}}, -{"type":"Feature","id":"47113","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-88.914747,35.795336],[-88.706624,35.789859],[-88.608039,35.789859],[-88.613516,35.587212],[-88.701147,35.477673],[-88.843547,35.428381],[-89.079056,35.433858],[-89.068102,35.691274],[-88.914747,35.795336]]]}}, -{"type":"Feature","id":"47115","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-85.601199,35.307888],[-85.557383,35.318842],[-85.387598,35.149057],[-85.475229,34.984749],[-85.606675,34.984749],[-85.864092,34.990226],[-85.875046,35.225734],[-85.601199,35.307888]]]}}, -{"type":"Feature","id":"47117","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-86.784218,35.707705],[-86.685633,35.707705],[-86.641817,35.685797],[-86.598002,35.362658],[-86.828033,35.264073],[-86.95948,35.417427],[-86.784218,35.707705]]]}}, -{"type":"Feature","id":"47119","properties":{"name":"Maury"},"geometry":{"type":"Polygon","coordinates":[[[-87.216896,35.850105],[-86.784218,35.707705],[-86.95948,35.417427],[-87.129265,35.455766],[-87.205942,35.433858],[-87.293573,35.444812],[-87.337389,35.658412],[-87.216896,35.850105]]]}}, -{"type":"Feature","id":"47121","properties":{"name":"Meigs"},"geometry":{"type":"Polygon","coordinates":[[[-84.620826,35.641982],[-84.861812,35.351704],[-84.872765,35.357181],[-84.943966,35.28598],[-85.015166,35.41195],[-84.724888,35.75152],[-84.620826,35.641982]]]}}, -{"type":"Feature","id":"47123","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-84.43461,35.669366],[-84.188148,35.60912],[-83.963593,35.461243],[-84.029317,35.291457],[-84.29221,35.209303],[-84.494857,35.28598],[-84.522241,35.60912],[-84.522241,35.620074],[-84.527718,35.625551],[-84.43461,35.669366]]]}}, -{"type":"Feature","id":"47125","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-87.112834,36.644262],[-87.118311,36.458046],[-87.288096,36.321122],[-87.512651,36.332076],[-87.594805,36.364938],[-87.63862,36.638785],[-87.337389,36.644262],[-87.112834,36.644262]]]}}, -{"type":"Feature","id":"47127","properties":{"name":"Moore"},"geometry":{"type":"Polygon","coordinates":[[[-86.258431,35.41195],[-86.263908,35.335273],[-86.318678,35.127149],[-86.526801,35.357181],[-86.258431,35.41195],[-86.258431,35.41195]]]}}, -{"type":"Feature","id":"47129","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-84.724888,36.375892],[-84.70298,36.370415],[-84.440087,36.162291],[-84.341502,36.047275],[-84.681073,35.910352],[-84.905627,36.156814],[-84.724888,36.375892]]]}}, -{"type":"Feature","id":"47131","properties":{"name":"Obion"},"geometry":{"type":"Polygon","coordinates":[[[-89.117394,36.501861],[-88.832593,36.501861],[-88.827116,36.501861],[-88.958563,36.222537],[-89.155733,36.206106],[-89.265272,36.206106],[-89.484349,36.211583],[-89.347426,36.501861],[-89.117394,36.501861]]]}}, -{"type":"Feature","id":"47133","properties":{"name":"Overton"},"geometry":{"type":"Polygon","coordinates":[[[-85.283536,36.534723],[-85.119228,36.408753],[-85.119228,36.14586],[-85.497137,36.304691],[-85.497137,36.403276],[-85.283536,36.529246],[-85.283536,36.534723]]]}}, -{"type":"Feature","id":"47135","properties":{"name":"Perry"},"geometry":{"type":"Polygon","coordinates":[[[-87.720774,35.795336],[-87.660528,35.60912],[-87.715298,35.48315],[-87.956283,35.461243],[-88.005575,35.422904],[-87.972714,35.817244],[-87.96176,35.839151],[-87.715298,35.839151],[-87.720774,35.795336]]]}}, -{"type":"Feature","id":"47137","properties":{"name":"Pickett"},"geometry":{"type":"Polygon","coordinates":[[[-85.278059,36.627831],[-84.976827,36.616877],[-84.785134,36.605923],[-84.730365,36.523769],[-85.009689,36.567584],[-85.119228,36.408753],[-85.283536,36.534723],[-85.283536,36.529246],[-85.278059,36.627831]]]}}, -{"type":"Feature","id":"47139","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-84.686549,35.253119],[-84.494857,35.28598],[-84.29221,35.209303],[-84.319594,34.990226],[-84.620826,34.990226],[-84.774181,34.990226],[-84.70298,35.242165],[-84.686549,35.253119]]]}}, -{"type":"Feature","id":"47141","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-85.497137,36.299214],[-85.497137,36.304691],[-85.119228,36.14586],[-85.102797,36.140383],[-85.261628,35.981552],[-85.508091,36.080137],[-85.645014,36.014414],[-85.809322,36.129429],[-85.781938,36.238968],[-85.497137,36.299214]]]}}, -{"type":"Feature","id":"47143","properties":{"name":"Rhea"},"geometry":{"type":"Polygon","coordinates":[[[-84.768704,35.80629],[-84.724888,35.75152],[-85.015166,35.41195],[-85.130182,35.455766],[-85.135659,35.455766],[-84.916581,35.762474],[-84.779657,35.822721],[-84.768704,35.80629]]]}}, -{"type":"Feature","id":"47145","properties":{"name":"Roane"},"geometry":{"type":"Polygon","coordinates":[[[-84.582488,35.641982],[-84.620826,35.641982],[-84.724888,35.75152],[-84.768704,35.80629],[-84.779657,35.822721],[-84.681073,35.910352],[-84.341502,36.047275],[-84.270302,35.910352],[-84.264825,35.899398],[-84.582488,35.641982]]]}}, -{"type":"Feature","id":"47147","properties":{"name":"Robertson"},"geometry":{"type":"Polygon","coordinates":[[[-86.76231,36.649739],[-86.56514,36.633308],[-86.756833,36.403276],[-86.76231,36.403276],[-86.915664,36.381369],[-87.118311,36.458046],[-87.112834,36.644262],[-87.058065,36.644262],[-86.76231,36.649739]]]}}, -{"type":"Feature","id":"47149","properties":{"name":"Rutherford"},"geometry":{"type":"Polygon","coordinates":[[[-86.515848,36.102045],[-86.15437,35.954167],[-86.209139,35.702228],[-86.247477,35.631028],[-86.521325,35.691274],[-86.641817,35.685797],[-86.685633,35.707705],[-86.619909,35.970598],[-86.515848,36.102045]]]}}, -{"type":"Feature","id":"47151","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-84.785134,36.605923],[-84.779657,36.605923],[-84.259348,36.589492],[-84.374364,36.21706],[-84.440087,36.162291],[-84.70298,36.370415],[-84.730365,36.523769],[-84.785134,36.605923]]]}}, -{"type":"Feature","id":"47153","properties":{"name":"Sequatchie"},"geometry":{"type":"Polygon","coordinates":[[[-85.425936,35.565304],[-85.22329,35.351704],[-85.387598,35.149057],[-85.557383,35.318842],[-85.590245,35.521489],[-85.606675,35.532443],[-85.557383,35.532443],[-85.425936,35.565304]]]}}, -{"type":"Feature","id":"47155","properties":{"name":"Sevier"},"geometry":{"type":"Polygon","coordinates":[[[-83.678792,36.030844],[-83.673316,36.036321],[-83.311837,35.893921],[-83.257068,35.713182],[-83.257068,35.696751],[-83.662362,35.570781],[-83.793808,35.888444],[-83.678792,36.030844]]]}}, -{"type":"Feature","id":"47157","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-89.774627,35.406473],[-89.632227,35.373611],[-89.643181,34.995703],[-89.725335,34.995703],[-89.829396,34.995703],[-90.311367,34.995703],[-90.075859,35.384565],[-89.774627,35.406473]]]}}, -{"type":"Feature","id":"47159","properties":{"name":"Smith"},"geometry":{"type":"Polygon","coordinates":[[[-85.979107,36.425184],[-85.825753,36.41423],[-85.781938,36.238968],[-85.809322,36.129429],[-86.061262,36.085614],[-86.137939,36.293737],[-85.979107,36.425184]]]}}, -{"type":"Feature","id":"47161","properties":{"name":"Stewart"},"geometry":{"type":"Polygon","coordinates":[[[-88.071299,36.677123],[-87.69339,36.638785],[-87.63862,36.638785],[-87.594805,36.364938],[-87.753636,36.34303],[-87.983668,36.353984],[-87.989145,36.359461],[-88.054868,36.496384],[-88.071299,36.677123]]]}}, -{"type":"Feature","id":"47163","properties":{"name":"Sullivan"},"geometry":{"type":"Polygon","coordinates":[[[-81.827587,36.616877],[-81.986418,36.507338],[-82.298603,36.397799],[-82.473866,36.441615],[-82.681989,36.430661],[-82.610789,36.594969],[-82.293127,36.594969],[-82.243834,36.594969],[-82.145249,36.594969],[-81.827587,36.616877]]]}}, -{"type":"Feature","id":"47165","properties":{"name":"Sumner"},"geometry":{"type":"Polygon","coordinates":[[[-86.411786,36.649739],[-86.203662,36.638785],[-86.231047,36.48543],[-86.285816,36.348507],[-86.36797,36.353984],[-86.592525,36.244445],[-86.756833,36.403276],[-86.56514,36.633308],[-86.411786,36.649739]]]}}, -{"type":"Feature","id":"47167","properties":{"name":"Tipton"},"geometry":{"type":"Polygon","coordinates":[[[-89.643181,35.647459],[-89.50078,35.581735],[-89.473395,35.400996],[-89.550073,35.400996],[-89.632227,35.373611],[-89.774627,35.406473],[-90.075859,35.384565],[-90.141582,35.439335],[-89.911551,35.53792],[-89.643181,35.647459]]]}}, -{"type":"Feature","id":"47169","properties":{"name":"Trousdale"},"geometry":{"type":"Polygon","coordinates":[[[-86.231047,36.48543],[-85.979107,36.425184],[-86.137939,36.293737],[-86.285816,36.348507],[-86.231047,36.48543]]]}}, -{"type":"Feature","id":"47171","properties":{"name":"Unicoi"},"geometry":{"type":"Polygon","coordinates":[[[-82.320511,36.260876],[-82.221926,36.156814],[-82.419096,36.07466],[-82.506727,35.976075],[-82.605312,36.041798],[-82.594358,36.096568],[-82.342419,36.255399],[-82.320511,36.260876]]]}}, -{"type":"Feature","id":"47173","properties":{"name":"Union"},"geometry":{"type":"Polygon","coordinates":[[[-83.903347,36.419707],[-83.667839,36.34303],[-83.733562,36.162291],[-83.925255,36.173245],[-83.941686,36.184199],[-84.001932,36.27183],[-83.903347,36.419707]]]}}, -{"type":"Feature","id":"47175","properties":{"name":"Van Buren"},"geometry":{"type":"Polygon","coordinates":[[[-85.42046,35.817244],[-85.267105,35.795336],[-85.272582,35.789859],[-85.256151,35.767951],[-85.256151,35.767951],[-85.256151,35.767951],[-85.425936,35.565304],[-85.557383,35.532443],[-85.601199,35.795336],[-85.42046,35.817244]]]}}, -{"type":"Feature","id":"47177","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-85.683353,35.833674],[-85.601199,35.795336],[-85.557383,35.532443],[-85.606675,35.532443],[-85.875046,35.521489],[-85.984584,35.658412],[-85.885999,35.839151],[-85.683353,35.833674]]]}}, -{"type":"Feature","id":"47179","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-82.473866,36.441615],[-82.298603,36.397799],[-82.342419,36.255399],[-82.594358,36.096568],[-82.632697,36.419707],[-82.703897,36.408753],[-82.681989,36.430661],[-82.473866,36.441615]]]}}, -{"type":"Feature","id":"47181","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-87.956283,35.461243],[-87.715298,35.48315],[-87.572897,35.400996],[-87.605759,35.00118],[-87.983668,35.006656],[-88.022006,35.390042],[-88.005575,35.422904],[-87.956283,35.461243]]]}}, -{"type":"Feature","id":"47183","properties":{"name":"Weakley"},"geometry":{"type":"Polygon","coordinates":[[[-88.827116,36.501861],[-88.816163,36.501861],[-88.514931,36.501861],[-88.531362,36.151337],[-88.690193,36.063706],[-88.958563,36.222537],[-88.827116,36.501861]]]}}, -{"type":"Feature","id":"47185","properties":{"name":"White"},"geometry":{"type":"Polygon","coordinates":[[[-85.508091,36.080137],[-85.261628,35.981552],[-85.267105,35.795336],[-85.42046,35.817244],[-85.601199,35.795336],[-85.683353,35.833674],[-85.645014,36.014414],[-85.508091,36.080137]]]}}, -{"type":"Feature","id":"47187","properties":{"name":"Williamson"},"geometry":{"type":"Polygon","coordinates":[[[-86.921141,36.052752],[-86.619909,35.970598],[-86.685633,35.707705],[-86.784218,35.707705],[-87.216896,35.850105],[-87.205942,35.959644],[-87.184034,36.047275],[-87.052588,36.047275],[-86.921141,36.052752]]]}}, -{"type":"Feature","id":"47189","properties":{"name":"Wilson"},"geometry":{"type":"Polygon","coordinates":[[[-86.36797,36.353984],[-86.285816,36.348507],[-86.137939,36.293737],[-86.061262,36.085614],[-86.017446,35.959644],[-86.15437,35.954167],[-86.515848,36.102045],[-86.592525,36.244445],[-86.36797,36.353984]]]}}, -{"type":"Feature","id":"48001","properties":{"name":"Anderson"},"geometry":{"type":"Polygon","coordinates":[[[-95.42683,32.08197],[-95.273475,31.594523],[-95.623999,31.54523],[-95.739015,31.501415],[-95.728061,31.643815],[-95.788308,31.61643],[-96.051201,32.005293],[-95.42683,32.08197]]]}}, -{"type":"Feature","id":"48003","properties":{"name":"Andrews"},"geometry":{"type":"Polygon","coordinates":[[[-102.995961,32.525602],[-102.212759,32.525602],[-102.212759,32.087447],[-102.289436,32.087447],[-102.798791,32.087447],[-103.061684,32.087447],[-103.067161,32.520126],[-102.995961,32.525602]]]}}, -{"type":"Feature","id":"48005","properties":{"name":"Angelina"},"geometry":{"type":"Polygon","coordinates":[[[-94.868182,31.528799],[-94.325965,31.222091],[-94.128795,31.101598],[-94.457411,31.035875],[-94.561473,31.057782],[-94.813412,31.13446],[-94.840797,31.145414],[-94.950336,31.342583],[-94.955813,31.386399],[-95.005105,31.424737],[-94.868182,31.528799]]]}}, -{"type":"Feature","id":"48007","properties":{"name":"Aransas"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-96.801542,28.275497],[-96.812495,28.21525],[-97.135635,27.903065],[-97.261605,28.078327],[-96.790588,28.319312],[-96.801542,28.275497]]],[[[-96.828926,28.111189],[-96.856311,28.061896],[-97.048004,27.837342],[-97.053481,27.842818],[-96.828926,28.111189]]]]}}, -{"type":"Feature","id":"48009","properties":{"name":"Archer"},"geometry":{"type":"Polygon","coordinates":[[[-98.43367,33.834591],[-98.422716,33.834591],[-98.422716,33.467636],[-98.422716,33.396436],[-98.953979,33.396436],[-98.953979,33.834591],[-98.43367,33.834591]]]}}, -{"type":"Feature","id":"48011","properties":{"name":"Armstrong"},"geometry":{"type":"Polygon","coordinates":[[[-101.621249,35.181919],[-101.084509,35.181919],[-101.089986,34.74924],[-101.473372,34.74924],[-101.626726,34.74924],[-101.621249,35.181919]]]}}, -{"type":"Feature","id":"48013","properties":{"name":"Atascosa"},"geometry":{"type":"Polygon","coordinates":[[[-98.800625,29.250392],[-98.406285,29.113469],[-98.192684,28.883437],[-98.099576,28.784852],[-98.335085,28.615067],[-98.581547,28.642452],[-98.800625,28.636975],[-98.800625,28.647929],[-98.806102,29.091561],[-98.806102,29.250392],[-98.800625,29.250392]]]}}, -{"type":"Feature","id":"48015","properties":{"name":"Austin"},"geometry":{"type":"Polygon","coordinates":[[[-96.379817,30.082887],[-96.144309,30.071933],[-96.03477,29.726886],[-96.089539,29.600916],[-96.17717,29.633778],[-96.57151,29.962394],[-96.620803,30.044549],[-96.379817,30.082887]]]}}, -{"type":"Feature","id":"48017","properties":{"name":"Bailey"},"geometry":{"type":"Polygon","coordinates":[[[-102.612575,34.311085],[-102.618052,33.823637],[-103.001438,33.823637],[-103.045254,33.823637],[-103.045254,34.300131],[-103.045254,34.311085],[-102.612575,34.311085]]]}}, -{"type":"Feature","id":"48019","properties":{"name":"Bandera"},"geometry":{"type":"Polygon","coordinates":[[[-99.600258,29.907625],[-98.915641,29.781655],[-98.778717,29.721409],[-98.806102,29.688547],[-99.414042,29.628301],[-99.605735,29.628301],[-99.600258,29.907625]]]}}, -{"type":"Feature","id":"48021","properties":{"name":"Bastrop"},"geometry":{"type":"Polygon","coordinates":[[[-97.332805,30.40055],[-97.026096,30.050025],[-97.316374,29.787132],[-97.650467,30.071933],[-97.371143,30.41698],[-97.332805,30.40055]]]}}, -{"type":"Feature","id":"48023","properties":{"name":"Baylor"},"geometry":{"type":"Polygon","coordinates":[[[-98.992318,33.834591],[-98.953979,33.834591],[-98.953979,33.396436],[-99.474288,33.396436],[-99.474288,33.736006],[-99.474288,33.834591],[-98.992318,33.834591]]]}}, -{"type":"Feature","id":"48025","properties":{"name":"Bee"},"geometry":{"type":"Polygon","coordinates":[[[-97.935268,28.713652],[-97.776437,28.669836],[-97.37662,28.390513],[-97.540929,28.165958],[-97.820252,28.176912],[-98.006468,28.691744],[-97.935268,28.713652]]]}}, -{"type":"Feature","id":"48027","properties":{"name":"Bell"},"geometry":{"type":"Polygon","coordinates":[[[-97.404005,31.304245],[-97.278035,31.282337],[-97.069912,30.986582],[-97.316374,30.751074],[-97.831206,30.904428],[-97.91336,31.035875],[-97.907884,31.068736],[-97.420436,31.320676],[-97.404005,31.304245]]]}}, -{"type":"Feature","id":"48029","properties":{"name":"Bexar"},"geometry":{"type":"Polygon","coordinates":[[[-98.64727,29.743317],[-98.313177,29.595439],[-98.132438,29.442085],[-98.285792,29.255869],[-98.406285,29.113469],[-98.800625,29.250392],[-98.806102,29.250392],[-98.806102,29.688547],[-98.778717,29.721409],[-98.64727,29.743317]]]}}, -{"type":"Feature","id":"48031","properties":{"name":"Blanco"},"geometry":{"type":"Polygon","coordinates":[[[-98.411762,30.504611],[-98.351516,30.488181],[-98.126961,30.427934],[-98.170777,30.356734],[-98.296746,30.039072],[-98.411762,29.93501],[-98.587024,30.137656],[-98.592501,30.499135],[-98.411762,30.504611]]]}}, -{"type":"Feature","id":"48033","properties":{"name":"Borden"},"geometry":{"type":"Polygon","coordinates":[[[-101.17214,32.963758],[-101.17214,32.525602],[-101.17214,32.525602],[-101.686972,32.525602],[-101.692449,32.963758],[-101.555526,32.963758],[-101.17214,32.963758]]]}}, -{"type":"Feature","id":"48035","properties":{"name":"Bosque"},"geometry":{"type":"Polygon","coordinates":[[[-97.62856,32.20794],[-97.617606,32.202463],[-97.475205,32.175078],[-97.278035,31.747877],[-97.606652,31.589046],[-97.688806,31.709538],[-97.765483,31.6712],[-98.006468,32.016247],[-97.864068,32.087447],[-97.62856,32.20794]]]}}, -{"type":"Feature","id":"48037","properties":{"name":"Bowie"},"geometry":{"type":"Polygon","coordinates":[[[-94.736735,33.703145],[-94.484796,33.637421],[-94.041164,33.54979],[-94.041164,33.270466],[-94.194518,33.297851],[-94.654581,33.270466],[-94.747689,33.330713],[-94.736735,33.703145]]]}}, -{"type":"Feature","id":"48039","properties":{"name":"Brazoria"},"geometry":{"type":"Polygon","coordinates":[[[-95.295383,29.595439],[-95.218706,29.557101],[-95.120121,29.07513],[-95.508984,28.823191],[-95.864985,29.223007],[-95.875939,29.228484],[-95.848554,29.261346],[-95.42683,29.579009],[-95.295383,29.595439]]]}}, -{"type":"Feature","id":"48041","properties":{"name":"Brazos"},"geometry":{"type":"Polygon","coordinates":[[[-96.237417,30.964674],[-96.166217,30.822274],[-96.155263,30.329349],[-96.297663,30.378642],[-96.566033,30.696304],[-96.242894,30.975628],[-96.237417,30.964674]]]}}, -{"type":"Feature","id":"48043","properties":{"name":"Brewster"},"geometry":{"type":"Polygon","coordinates":[[[-103.346485,30.603196],[-102.56876,30.050025],[-102.322297,29.88024],[-102.678299,29.73784],[-102.919284,29.190146],[-103.280762,28.982022],[-103.790117,29.261346],[-103.801071,30.411504],[-103.439593,30.663443],[-103.346485,30.603196]]]}}, -{"type":"Feature","id":"48045","properties":{"name":"Briscoe"},"geometry":{"type":"Polygon","coordinates":[[[-101.473372,34.74924],[-101.089986,34.74924],[-100.947585,34.74924],[-100.947585,34.311085],[-101.040693,34.311085],[-101.473372,34.311085],[-101.473372,34.74924]]]}}, -{"type":"Feature","id":"48047","properties":{"name":"Brooks"},"geometry":{"type":"Polygon","coordinates":[[[-98.521301,27.26774],[-98.231023,27.262263],[-98.055761,27.262263],[-97.984561,27.207493],[-97.984561,26.780292],[-98.318654,26.785769],[-98.422716,26.785769],[-98.521301,27.26774]]]}}, -{"type":"Feature","id":"48049","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-99.118287,32.08197],[-98.926594,32.076493],[-98.669178,31.698584],[-98.992318,31.484984],[-99.090903,31.463076],[-99.200441,31.468553],[-99.194965,32.08197],[-99.118287,32.08197]]]}}, -{"type":"Feature","id":"48051","properties":{"name":"Burleson"},"geometry":{"type":"Polygon","coordinates":[[[-96.620803,30.729166],[-96.566033,30.696304],[-96.297663,30.378642],[-96.64271,30.296488],[-96.96585,30.559381],[-96.620803,30.729166]]]}}, -{"type":"Feature","id":"48053","properties":{"name":"Burnet"},"geometry":{"type":"Polygon","coordinates":[[[-98.017422,31.035875],[-97.91336,31.035875],[-97.831206,30.904428],[-98.050284,30.625104],[-98.126961,30.427934],[-98.351516,30.488181],[-98.444624,30.920859],[-98.439147,31.030398],[-98.017422,31.035875]]]}}, -{"type":"Feature","id":"48055","properties":{"name":"Caldwell"},"geometry":{"type":"Polygon","coordinates":[[[-97.666898,30.066456],[-97.650467,30.071933],[-97.316374,29.787132],[-97.316374,29.787132],[-97.634037,29.650209],[-97.798345,29.754271],[-97.875022,29.858333],[-97.710714,30.022641],[-97.666898,30.066456]]]}}, -{"type":"Feature","id":"48057","properties":{"name":"Calhoun"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-96.576987,28.708175],[-96.325048,28.675313],[-96.325048,28.642452],[-96.576987,28.702698],[-96.576987,28.708175]]],[[[-96.763203,28.41242],[-96.889173,28.505528],[-96.653664,28.702698],[-96.763203,28.41242]]]]}}, -{"type":"Feature","id":"48059","properties":{"name":"Callahan"},"geometry":{"type":"Polygon","coordinates":[[[-99.194965,32.514649],[-99.11281,32.514649],[-99.118287,32.08197],[-99.194965,32.08197],[-99.63312,32.08197],[-99.627643,32.514649],[-99.611212,32.514649],[-99.194965,32.514649]]]}}, -{"type":"Feature","id":"48061","properties":{"name":"Cameron"},"geometry":{"type":"Polygon","coordinates":[[[-97.864068,26.347614],[-97.382097,26.413337],[-97.371143,25.838258],[-97.864068,26.051859],[-97.864068,26.347614]]]}}, -{"type":"Feature","id":"48063","properties":{"name":"Camp"},"geometry":{"type":"Polygon","coordinates":[[[-95.125598,33.034958],[-94.818889,32.980189],[-94.720304,32.903511],[-94.780551,32.903511],[-95.152983,32.903511],[-95.152983,33.01305],[-95.125598,33.034958]]]}}, -{"type":"Feature","id":"48065","properties":{"name":"Carson"},"geometry":{"type":"Polygon","coordinates":[[[-101.084509,35.625551],[-101.084509,35.620074],[-101.084509,35.181919],[-101.621249,35.181919],[-101.621249,35.620074],[-101.621249,35.625551],[-101.084509,35.625551],[-101.084509,35.625551]]]}}, -{"type":"Feature","id":"48067","properties":{"name":"Cass"},"geometry":{"type":"Polygon","coordinates":[[[-94.194518,33.297851],[-94.041164,33.270466],[-94.041164,33.018527],[-94.041164,32.881604],[-94.249287,32.881604],[-94.654581,32.881604],[-94.654581,33.270466],[-94.194518,33.297851]]]}}, -{"type":"Feature","id":"48069","properties":{"name":"Castro"},"geometry":{"type":"Polygon","coordinates":[[[-102.004635,34.74924],[-101.999158,34.74924],[-101.999158,34.311085],[-102.092266,34.311085],[-102.327774,34.311085],[-102.524944,34.311085],[-102.524944,34.74924],[-102.168943,34.74924],[-102.004635,34.74924]]]}}, -{"type":"Feature","id":"48071","properties":{"name":"Chambers"},"geometry":{"type":"Polygon","coordinates":[[[-94.44098,29.891194],[-94.353349,29.562578],[-94.36978,29.557101],[-94.36978,29.595439],[-94.512181,29.54067],[-94.928428,29.672117],[-94.97772,29.885717],[-94.44098,29.891194]]]}}, -{"type":"Feature","id":"48073","properties":{"name":"Cherokee"},"geometry":{"type":"Polygon","coordinates":[[[-94.983197,32.13674],[-94.939382,31.846462],[-94.868182,31.528799],[-95.005105,31.424737],[-95.273475,31.594523],[-95.42683,32.08197],[-95.459691,32.13674],[-94.983197,32.13674]]]}}, -{"type":"Feature","id":"48075","properties":{"name":"Childress"},"geometry":{"type":"Polygon","coordinates":[[[-100.416322,34.74924],[-100.000075,34.743763],[-100.000075,34.563024],[-100.000075,34.311085],[-100.416322,34.311085],[-100.416322,34.74924]]]}}, -{"type":"Feature","id":"48077","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-98.137915,34.1413],[-97.979084,33.889361],[-97.979084,33.467636],[-98.422716,33.467636],[-98.422716,33.834591],[-98.422716,34.081054],[-98.137915,34.1413]]]}}, -{"type":"Feature","id":"48079","properties":{"name":"Cochran"},"geometry":{"type":"Polygon","coordinates":[[[-103.001438,33.823637],[-102.618052,33.823637],[-102.596144,33.390959],[-103.056207,33.390959],[-103.050731,33.571698],[-103.045254,33.823637],[-103.001438,33.823637]]]}}, -{"type":"Feature","id":"48081","properties":{"name":"Coke"},"geometry":{"type":"Polygon","coordinates":[[[-100.821616,32.087447],[-100.662785,32.087447],[-100.235583,32.08197],[-100.235583,31.693108],[-100.827093,31.698584],[-100.821616,32.087447]]]}}, -{"type":"Feature","id":"48083","properties":{"name":"Coleman"},"geometry":{"type":"Polygon","coordinates":[[[-99.63312,32.08197],[-99.194965,32.08197],[-99.200441,31.468553],[-99.430473,31.468553],[-99.600258,31.490461],[-99.720751,31.578092],[-99.715274,32.08197],[-99.63312,32.08197]]]}}, -{"type":"Feature","id":"48085","properties":{"name":"Collin"},"geometry":{"type":"Polygon","coordinates":[[[-96.834403,33.40739],[-96.834403,33.40739],[-96.385294,33.396436],[-96.297663,33.35262],[-96.297663,32.980189],[-96.440064,32.980189],[-96.516741,32.980189],[-96.845357,32.985665],[-96.834403,33.40739]]]}}, -{"type":"Feature","id":"48087","properties":{"name":"Collingsworth"},"geometry":{"type":"Polygon","coordinates":[[[-100.093183,35.181919],[-100.000075,35.181919],[-100.000075,35.028564],[-100.000075,34.743763],[-100.416322,34.74924],[-100.542292,34.74924],[-100.536815,35.181919],[-100.093183,35.181919]]]}}, -{"type":"Feature","id":"48089","properties":{"name":"Colorado"},"geometry":{"type":"Polygon","coordinates":[[[-96.57151,29.962394],[-96.17717,29.633778],[-96.64271,29.250392],[-96.659141,29.261346],[-96.872742,29.633778],[-96.57151,29.962394]]]}}, -{"type":"Feature","id":"48091","properties":{"name":"Comal"},"geometry":{"type":"Polygon","coordinates":[[[-98.296746,30.039072],[-98.000992,29.754271],[-98.313177,29.595439],[-98.64727,29.743317],[-98.411762,29.93501],[-98.296746,30.039072]]]}}, -{"type":"Feature","id":"48093","properties":{"name":"Comanche"},"geometry":{"type":"Polygon","coordinates":[[[-98.548686,32.262709],[-98.209115,31.917662],[-98.461055,31.682154],[-98.669178,31.698584],[-98.926594,32.076493],[-98.548686,32.262709]]]}}, -{"type":"Feature","id":"48095","properties":{"name":"Concho"},"geometry":{"type":"Polygon","coordinates":[[[-99.726228,31.578092],[-99.720751,31.578092],[-99.600258,31.490461],[-99.605735,31.085167],[-100.115091,31.090644],[-100.109614,31.578092],[-99.726228,31.578092]]]}}, -{"type":"Feature","id":"48097","properties":{"name":"Cooke"},"geometry":{"type":"Polygon","coordinates":[[[-96.943942,33.949607],[-96.943942,33.418344],[-97.382097,33.429298],[-97.486159,33.434775],[-97.486159,33.916745],[-96.943942,33.949607]]]}}, -{"type":"Feature","id":"48099","properties":{"name":"Coryell"},"geometry":{"type":"Polygon","coordinates":[[[-97.688806,31.709538],[-97.606652,31.589046],[-97.420436,31.320676],[-97.907884,31.068736],[-98.181731,31.463076],[-97.765483,31.6712],[-97.688806,31.709538]]]}}, -{"type":"Feature","id":"48101","properties":{"name":"Cottle"},"geometry":{"type":"Polygon","coordinates":[[[-100.514907,34.316562],[-100.416322,34.311085],[-100.000075,34.311085],[-100.000075,34.223454],[-100.049367,33.834591],[-100.520384,33.834591],[-100.514907,34.316562]]]}}, -{"type":"Feature","id":"48103","properties":{"name":"Crane"},"geometry":{"type":"Polygon","coordinates":[[[-102.76593,31.649292],[-102.316821,31.649292],[-102.30039,31.085167],[-102.388021,31.085167],[-102.76593,31.293291],[-102.76593,31.649292]]]}}, -{"type":"Feature","id":"48105","properties":{"name":"Crockett"},"geometry":{"type":"Polygon","coordinates":[[[-102.388021,31.085167],[-102.30039,31.085167],[-101.774603,31.07969],[-101.276202,31.07969],[-100.964016,31.085167],[-100.958539,30.707258],[-100.958539,30.285534],[-101.544572,30.285534],[-101.758173,30.285534],[-101.769126,30.652489],[-102.388021,31.085167]]]}}, -{"type":"Feature","id":"48107","properties":{"name":"Crosby"},"geometry":{"type":"Polygon","coordinates":[[[-101.561003,33.829114],[-101.040693,33.834591],[-101.040693,33.396436],[-101.111894,33.396436],[-101.555526,33.396436],[-101.561003,33.829114]]]}}, -{"type":"Feature","id":"48109","properties":{"name":"Culberson"},"geometry":{"type":"Polygon","coordinates":[[[-104.847167,31.999816],[-104.025626,31.999816],[-104.102303,31.107075],[-104.918367,30.663443],[-104.918367,31.999816],[-104.847167,31.999816]]]}}, -{"type":"Feature","id":"48111","properties":{"name":"Dallam"},"geometry":{"type":"Polygon","coordinates":[[[-103.001438,36.501861],[-102.163466,36.501861],[-102.163466,36.052752],[-102.30039,36.052752],[-103.039777,36.052752],[-103.001438,36.501861]]]}}, -{"type":"Feature","id":"48113","properties":{"name":"Dallas"},"geometry":{"type":"Polygon","coordinates":[[[-96.856311,32.985665],[-96.845357,32.985665],[-96.516741,32.980189],[-96.516741,32.81588],[-96.527695,32.54751],[-97.03705,32.54751],[-97.031573,32.985665],[-96.856311,32.985665]]]}}, -{"type":"Feature","id":"48115","properties":{"name":"Dawson"},"geometry":{"type":"Polygon","coordinates":[[[-101.692449,32.963758],[-101.686972,32.525602],[-102.201805,32.525602],[-102.207282,32.958281],[-102.075835,32.958281],[-101.692449,32.963758]]]}}, -{"type":"Feature","id":"48117","properties":{"name":"Deaf Smith"},"geometry":{"type":"Polygon","coordinates":[[[-102.579714,35.187396],[-102.168943,35.181919],[-102.168943,34.74924],[-102.524944,34.74924],[-103.045254,34.74924],[-103.045254,34.951887],[-103.039777,35.181919],[-102.579714,35.187396]]]}}, -{"type":"Feature","id":"48119","properties":{"name":"Delta"},"geometry":{"type":"Polygon","coordinates":[[[-95.651384,33.484067],[-95.306337,33.380005],[-95.306337,33.380005],[-95.306337,33.374528],[-95.492553,33.35262],[-95.859508,33.221174],[-95.859508,33.40739],[-95.859508,33.462159],[-95.651384,33.484067]]]}}, -{"type":"Feature","id":"48121","properties":{"name":"Denton"},"geometry":{"type":"Polygon","coordinates":[[[-97.382097,33.429298],[-96.943942,33.418344],[-96.834403,33.40739],[-96.834403,33.40739],[-96.845357,32.985665],[-96.856311,32.985665],[-97.031573,32.985665],[-97.398528,32.991142],[-97.382097,33.429298]]]}}, -{"type":"Feature","id":"48123","properties":{"name":"DeWitt"},"geometry":{"type":"Polygon","coordinates":[[[-97.239697,29.381839],[-96.976804,29.102515],[-97.30542,28.861529],[-97.57379,28.812237],[-97.612129,29.107992],[-97.239697,29.381839]]]}}, -{"type":"Feature","id":"48125","properties":{"name":"Dickens"},"geometry":{"type":"Polygon","coordinates":[[[-100.90377,33.834591],[-100.520384,33.834591],[-100.514907,33.396436],[-100.816139,33.396436],[-101.040693,33.396436],[-101.040693,33.834591],[-100.90377,33.834591]]]}}, -{"type":"Feature","id":"48127","properties":{"name":"Dimmit"},"geometry":{"type":"Polygon","coordinates":[[[-99.780997,28.642452],[-99.408565,28.642452],[-99.397611,28.642452],[-99.392134,28.204297],[-100.115091,28.19882],[-100.115091,28.647929],[-99.780997,28.642452]]]}}, -{"type":"Feature","id":"48129","properties":{"name":"Donley"},"geometry":{"type":"Polygon","coordinates":[[[-100.969493,35.181919],[-100.536815,35.181919],[-100.542292,34.74924],[-100.947585,34.74924],[-101.089986,34.74924],[-101.084509,35.181919],[-100.969493,35.181919]]]}}, -{"type":"Feature","id":"48131","properties":{"name":"Duval"},"geometry":{"type":"Polygon","coordinates":[[[-98.335085,28.056419],[-98.2365,28.056419],[-98.231023,27.262263],[-98.521301,27.26774],[-98.800625,27.355371],[-98.800625,28.056419],[-98.335085,28.056419]]]}}, -{"type":"Feature","id":"48133","properties":{"name":"Eastland"},"geometry":{"type":"Polygon","coordinates":[[[-98.740378,32.514649],[-98.57607,32.514649],[-98.477485,32.514649],[-98.548686,32.262709],[-98.926594,32.076493],[-99.118287,32.08197],[-99.11281,32.514649],[-99.09638,32.514649],[-98.740378,32.514649]]]}}, -{"type":"Feature","id":"48135","properties":{"name":"Ector"},"geometry":{"type":"Polygon","coordinates":[[[-102.289436,32.087447],[-102.289436,31.649292],[-102.316821,31.649292],[-102.76593,31.649292],[-102.798791,31.649292],[-102.798791,32.087447],[-102.289436,32.087447]]]}}, -{"type":"Feature","id":"48137","properties":{"name":"Edwards"},"geometry":{"type":"Polygon","coordinates":[[[-99.753612,30.291011],[-99.759089,30.071933],[-100.016506,29.622824],[-100.109614,29.622824],[-100.575153,29.622824],[-100.701123,29.622824],[-100.701123,30.291011],[-100.115091,30.291011],[-99.753612,30.291011]]]}}, -{"type":"Feature","id":"48139","properties":{"name":"Ellis"},"geometry":{"type":"Polygon","coordinates":[[[-97.086342,32.54751],[-97.03705,32.54751],[-96.527695,32.54751],[-96.451017,32.361294],[-96.385294,32.328433],[-96.89465,32.076493],[-97.086342,32.268186],[-97.086342,32.54751]]]}}, -{"type":"Feature","id":"48141","properties":{"name":"El Paso"},"geometry":{"type":"Polygon","coordinates":[[[-105.997324,31.999816],[-105.997324,31.386399],[-106.528588,31.786216],[-106.375233,31.999816],[-105.997324,31.999816]]]}}, -{"type":"Feature","id":"48143","properties":{"name":"Erath"},"geometry":{"type":"Polygon","coordinates":[[[-98.066715,32.509172],[-97.946222,32.235325],[-97.864068,32.087447],[-98.006468,32.016247],[-98.209115,31.917662],[-98.548686,32.262709],[-98.477485,32.514649],[-98.066715,32.509172]]]}}, -{"type":"Feature","id":"48145","properties":{"name":"Falls"},"geometry":{"type":"Polygon","coordinates":[[[-96.801542,31.523322],[-96.598895,31.222091],[-96.828926,31.107075],[-97.069912,30.986582],[-97.278035,31.282337],[-96.801542,31.523322]]]}}, -{"type":"Feature","id":"48147","properties":{"name":"Fannin"},"geometry":{"type":"Polygon","coordinates":[[[-95.843077,33.840068],[-95.859508,33.462159],[-95.859508,33.40739],[-96.297663,33.35262],[-96.385294,33.396436],[-96.379817,33.725052],[-95.843077,33.840068]]]}}, -{"type":"Feature","id":"48149","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-96.801542,30.154087],[-96.796065,30.159564],[-96.620803,30.044549],[-96.57151,29.962394],[-96.872742,29.633778],[-97.141112,29.628301],[-97.316374,29.787132],[-97.316374,29.787132],[-97.026096,30.050025],[-96.801542,30.154087]]]}}, -{"type":"Feature","id":"48151","properties":{"name":"Fisher"},"geometry":{"type":"Polygon","coordinates":[[[-100.520384,32.963758],[-100.142475,32.958281],[-100.147952,32.520126],[-100.662785,32.525602],[-100.657308,32.963758],[-100.520384,32.963758]]]}}, -{"type":"Feature","id":"48153","properties":{"name":"Floyd"},"geometry":{"type":"Polygon","coordinates":[[[-101.473372,34.311085],[-101.040693,34.311085],[-101.040693,33.834591],[-101.561003,33.829114],[-101.56648,34.311085],[-101.473372,34.311085]]]}}, -{"type":"Feature","id":"48155","properties":{"name":"Foard"},"geometry":{"type":"Polygon","coordinates":[[[-100.000075,34.223454],[-99.474288,34.08653],[-99.474288,33.834591],[-99.474288,33.736006],[-99.868628,33.834591],[-99.994598,33.834591],[-100.049367,33.834591],[-100.000075,34.223454]]]}}, -{"type":"Feature","id":"48157","properties":{"name":"Fort Bend"},"geometry":{"type":"Polygon","coordinates":[[[-95.826646,29.787132],[-95.826646,29.787132],[-95.42683,29.579009],[-95.848554,29.261346],[-96.089539,29.600916],[-96.03477,29.726886],[-95.826646,29.787132]]]}}, -{"type":"Feature","id":"48159","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-95.306337,33.380005],[-95.125598,33.390959],[-95.125598,33.034958],[-95.152983,33.01305],[-95.306337,32.963758],[-95.306337,33.374528],[-95.306337,33.380005]]]}}, -{"type":"Feature","id":"48161","properties":{"name":"Freestone"},"geometry":{"type":"Polygon","coordinates":[[[-96.051201,32.005293],[-95.788308,31.61643],[-96.237417,31.413784],[-96.494833,31.797169],[-96.056678,32.01077],[-96.051201,32.005293]]]}}, -{"type":"Feature","id":"48163","properties":{"name":"Frio"},"geometry":{"type":"Polygon","coordinates":[[[-98.904687,29.091561],[-98.806102,29.091561],[-98.800625,28.647929],[-99.397611,28.642452],[-99.408565,28.642452],[-99.414042,29.091561],[-98.904687,29.091561]]]}}, -{"type":"Feature","id":"48165","properties":{"name":"Gaines"},"geometry":{"type":"Polygon","coordinates":[[[-103.067161,32.958281],[-102.596144,32.958281],[-102.207282,32.958281],[-102.201805,32.525602],[-102.212759,32.525602],[-102.995961,32.525602],[-103.067161,32.520126],[-103.067161,32.958281]]]}}, -{"type":"Feature","id":"48167","properties":{"name":"Galveston"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-94.36978,29.595439],[-94.36978,29.557101],[-94.512181,29.54067],[-94.36978,29.595439]]],[[[-95.202275,29.562578],[-95.016059,29.557101],[-95.120121,29.07513],[-95.218706,29.557101],[-95.202275,29.562578]]]]}}, -{"type":"Feature","id":"48169","properties":{"name":"Garza"},"geometry":{"type":"Polygon","coordinates":[[[-101.111894,33.396436],[-101.040693,33.396436],[-101.040693,32.969235],[-101.17214,32.963758],[-101.555526,32.963758],[-101.555526,33.396436],[-101.111894,33.396436]]]}}, -{"type":"Feature","id":"48171","properties":{"name":"Gillespie"},"geometry":{"type":"Polygon","coordinates":[[[-99.304503,30.499135],[-98.964933,30.499135],[-98.592501,30.499135],[-98.587024,30.137656],[-98.921118,30.137656],[-99.304503,30.285534],[-99.304503,30.499135]]]}}, -{"type":"Feature","id":"48173","properties":{"name":"Glasscock"},"geometry":{"type":"Polygon","coordinates":[[[-101.747219,32.087447],[-101.692449,32.087447],[-101.265248,32.087447],[-101.265248,31.649292],[-101.686972,31.649292],[-101.774603,31.649292],[-101.774603,32.087447],[-101.747219,32.087447]]]}}, -{"type":"Feature","id":"48175","properties":{"name":"Goliad"},"geometry":{"type":"Polygon","coordinates":[[[-97.30542,28.861529],[-97.16302,28.554821],[-97.37662,28.390513],[-97.776437,28.669836],[-97.57379,28.812237],[-97.30542,28.861529]]]}}, -{"type":"Feature","id":"48177","properties":{"name":"Gonzales"},"geometry":{"type":"Polygon","coordinates":[[[-97.316374,29.787132],[-97.141112,29.628301],[-97.239697,29.381839],[-97.612129,29.107992],[-97.727145,29.223007],[-97.84216,29.376362],[-97.634037,29.650209],[-97.316374,29.787132]]]}}, -{"type":"Feature","id":"48179","properties":{"name":"Gray"},"geometry":{"type":"Polygon","coordinates":[[[-101.084509,35.620074],[-100.542292,35.620074],[-100.536815,35.181919],[-100.969493,35.181919],[-101.084509,35.181919],[-101.084509,35.620074]]]}}, -{"type":"Feature","id":"48181","properties":{"name":"Grayson"},"geometry":{"type":"Polygon","coordinates":[[[-96.587941,33.894838],[-96.379817,33.725052],[-96.385294,33.396436],[-96.834403,33.40739],[-96.943942,33.418344],[-96.943942,33.949607],[-96.932988,33.955084],[-96.587941,33.894838]]]}}, -{"type":"Feature","id":"48183","properties":{"name":"Gregg"},"geometry":{"type":"Polygon","coordinates":[[[-94.703873,32.651572],[-94.577904,32.394156],[-94.988674,32.366771],[-94.988674,32.536556],[-94.703873,32.651572]]]}}, -{"type":"Feature","id":"48185","properties":{"name":"Grimes"},"geometry":{"type":"Polygon","coordinates":[[[-96.166217,30.822274],[-95.864985,30.86609],[-95.832123,30.630581],[-95.804738,30.247195],[-95.821169,30.247195],[-96.095016,30.225288],[-96.155263,30.329349],[-96.166217,30.822274]]]}}, -{"type":"Feature","id":"48187","properties":{"name":"Guadalupe"},"geometry":{"type":"Polygon","coordinates":[[[-97.798345,29.754271],[-97.634037,29.650209],[-97.84216,29.376362],[-98.132438,29.442085],[-98.313177,29.595439],[-98.000992,29.754271],[-97.875022,29.858333],[-97.798345,29.754271]]]}}, -{"type":"Feature","id":"48189","properties":{"name":"Hale"},"geometry":{"type":"Polygon","coordinates":[[[-102.092266,34.311085],[-101.999158,34.311085],[-101.56648,34.311085],[-101.561003,33.829114],[-101.571957,33.829114],[-102.086789,33.823637],[-102.092266,34.311085]]]}}, -{"type":"Feature","id":"48191","properties":{"name":"Hall"},"geometry":{"type":"Polygon","coordinates":[[[-100.947585,34.74924],[-100.542292,34.74924],[-100.416322,34.74924],[-100.416322,34.311085],[-100.514907,34.316562],[-100.673738,34.311085],[-100.947585,34.311085],[-100.947585,34.74924]]]}}, -{"type":"Feature","id":"48193","properties":{"name":"Hamilton"},"geometry":{"type":"Polygon","coordinates":[[[-98.006468,32.016247],[-97.765483,31.6712],[-98.181731,31.463076],[-98.269362,31.413784],[-98.461055,31.682154],[-98.209115,31.917662],[-98.006468,32.016247]]]}}, -{"type":"Feature","id":"48195","properties":{"name":"Hansford"},"geometry":{"type":"Polygon","coordinates":[[[-101.084509,36.501861],[-101.084509,36.058229],[-101.084509,36.052752],[-101.621249,36.052752],[-101.621249,36.501861],[-101.084509,36.501861]]]}}, -{"type":"Feature","id":"48197","properties":{"name":"Hardeman"},"geometry":{"type":"Polygon","coordinates":[[[-99.84672,34.508255],[-99.474288,34.398716],[-99.474288,34.08653],[-100.000075,34.223454],[-100.000075,34.311085],[-100.000075,34.563024],[-99.84672,34.508255]]]}}, -{"type":"Feature","id":"48199","properties":{"name":"Hardin"},"geometry":{"type":"Polygon","coordinates":[[[-94.44098,30.526519],[-94.074025,30.526519],[-94.117841,30.241718],[-94.117841,30.159564],[-94.216426,30.175995],[-94.446457,30.110272],[-94.731258,30.488181],[-94.545042,30.526519],[-94.44098,30.526519]]]}}, -{"type":"Feature","id":"48201","properties":{"name":"Harris"},"geometry":{"type":"Polygon","coordinates":[[[-95.218706,30.066456],[-95.098213,30.165041],[-94.97772,29.885717],[-94.928428,29.672117],[-95.016059,29.557101],[-95.202275,29.562578],[-95.218706,29.557101],[-95.295383,29.595439],[-95.42683,29.579009],[-95.826646,29.787132],[-95.804738,30.088364],[-95.218706,30.066456]]]}}, -{"type":"Feature","id":"48203","properties":{"name":"Harrison"},"geometry":{"type":"Polygon","coordinates":[[[-94.703873,32.793973],[-94.041164,32.695388],[-94.041164,32.394156],[-94.462888,32.377725],[-94.490273,32.394156],[-94.577904,32.394156],[-94.703873,32.651572],[-94.703873,32.793973]]]}}, -{"type":"Feature","id":"48205","properties":{"name":"Hartley"},"geometry":{"type":"Polygon","coordinates":[[[-102.30039,36.052752],[-102.163466,36.052752],[-102.163466,35.625551],[-103.039777,35.620074],[-103.039777,35.740566],[-103.039777,36.052752],[-102.30039,36.052752]]]}}, -{"type":"Feature","id":"48207","properties":{"name":"Haskell"},"geometry":{"type":"Polygon","coordinates":[[[-99.518104,33.396436],[-99.474288,33.396436],[-99.468812,32.958281],[-99.611212,32.958281],[-99.989121,32.958281],[-99.989121,33.396436],[-99.518104,33.396436]]]}}, -{"type":"Feature","id":"48209","properties":{"name":"Hays"},"geometry":{"type":"Polygon","coordinates":[[[-98.170777,30.356734],[-97.710714,30.022641],[-97.875022,29.858333],[-98.000992,29.754271],[-98.296746,30.039072],[-98.170777,30.356734]]]}}, -{"type":"Feature","id":"48211","properties":{"name":"Hemphill"},"geometry":{"type":"Polygon","coordinates":[[[-100.000075,36.058229],[-100.000075,35.882967],[-100.000075,35.620074],[-100.542292,35.620074],[-100.542292,36.058229],[-100.000075,36.058229]]]}}, -{"type":"Feature","id":"48213","properties":{"name":"Henderson"},"geometry":{"type":"Polygon","coordinates":[[[-96.215509,32.361294],[-96.078585,32.355817],[-95.448737,32.355817],[-95.459691,32.13674],[-95.42683,32.08197],[-96.051201,32.005293],[-96.056678,32.01077],[-96.385294,32.328433],[-96.451017,32.361294],[-96.215509,32.361294]]]}}, -{"type":"Feature","id":"48215","properties":{"name":"Hidalgo"},"geometry":{"type":"Polygon","coordinates":[[[-98.318654,26.785769],[-97.984561,26.780292],[-97.957176,26.610507],[-97.864068,26.347614],[-97.864068,26.051859],[-98.587024,26.254506],[-98.318654,26.785769]]]}}, -{"type":"Feature","id":"48217","properties":{"name":"Hill"},"geometry":{"type":"Polygon","coordinates":[[[-97.113727,32.257232],[-97.086342,32.268186],[-96.89465,32.076493],[-96.719387,31.8136],[-96.932988,31.709538],[-97.080866,31.840985],[-97.278035,31.747877],[-97.475205,32.175078],[-97.113727,32.257232]]]}}, -{"type":"Feature","id":"48219","properties":{"name":"Hockley"},"geometry":{"type":"Polygon","coordinates":[[[-102.618052,33.823637],[-102.086789,33.823637],[-102.075835,33.390959],[-102.366113,33.390959],[-102.596144,33.390959],[-102.618052,33.823637]]]}}, -{"type":"Feature","id":"48221","properties":{"name":"Hood"},"geometry":{"type":"Polygon","coordinates":[[[-98.066715,32.558464],[-97.617606,32.552987],[-97.617606,32.317479],[-97.946222,32.235325],[-98.066715,32.509172],[-98.066715,32.558464]]]}}, -{"type":"Feature","id":"48223","properties":{"name":"Hopkins"},"geometry":{"type":"Polygon","coordinates":[[[-95.492553,33.35262],[-95.306337,33.374528],[-95.306337,32.963758],[-95.667815,32.958281],[-95.864985,32.980189],[-95.859508,33.221174],[-95.492553,33.35262]]]}}, -{"type":"Feature","id":"48225","properties":{"name":"Houston"},"geometry":{"type":"Polygon","coordinates":[[[-95.623999,31.54523],[-95.273475,31.594523],[-95.005105,31.424737],[-94.955813,31.386399],[-95.432306,31.057782],[-95.618522,30.931813],[-95.7664,31.096121],[-95.739015,31.501415],[-95.623999,31.54523]]]}}, -{"type":"Feature","id":"48227","properties":{"name":"Howard"},"geometry":{"type":"Polygon","coordinates":[[[-101.17214,32.525602],[-101.183094,32.087447],[-101.265248,32.087447],[-101.692449,32.087447],[-101.686972,32.525602],[-101.17214,32.525602]]]}}, -{"type":"Feature","id":"48229","properties":{"name":"Hudspeth"},"geometry":{"type":"Polygon","coordinates":[[[-105.997324,31.999816],[-104.918367,31.999816],[-104.918367,30.663443],[-104.98409,30.630581],[-104.98409,30.630581],[-105.997324,31.386399],[-105.997324,31.999816]]]}}, -{"type":"Feature","id":"48231","properties":{"name":"Hunt"},"geometry":{"type":"Polygon","coordinates":[[[-95.859508,33.40739],[-95.859508,33.221174],[-95.864985,32.980189],[-95.936185,32.837788],[-96.062155,32.837788],[-96.078585,32.837788],[-96.297663,32.843265],[-96.297663,32.980189],[-96.297663,33.35262],[-95.859508,33.40739]]]}}, -{"type":"Feature","id":"48233","properties":{"name":"Hutchinson"},"geometry":{"type":"Polygon","coordinates":[[[-101.621249,36.052752],[-101.084509,36.052752],[-101.084509,35.625551],[-101.621249,35.625551],[-101.621249,36.052752]]]}}, -{"type":"Feature","id":"48235","properties":{"name":"Irion"},"geometry":{"type":"Polygon","coordinates":[[[-101.265248,31.528799],[-100.695646,31.523322],[-100.690169,31.085167],[-100.964016,31.085167],[-101.276202,31.07969],[-101.265248,31.528799]]]}}, -{"type":"Feature","id":"48237","properties":{"name":"Jack"},"geometry":{"type":"Polygon","coordinates":[[[-98.422716,33.467636],[-97.979084,33.467636],[-97.918837,33.434775],[-97.924314,33.002096],[-98.055761,33.002096],[-98.055761,33.002096],[-98.428193,33.007573],[-98.422716,33.396436],[-98.422716,33.467636]]]}}, -{"type":"Feature","id":"48239","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-96.659141,29.261346],[-96.64271,29.250392],[-96.308617,28.965591],[-96.325048,28.675313],[-96.576987,28.708175],[-96.576987,28.702698],[-96.64271,28.713652],[-96.938465,29.064176],[-96.659141,29.261346]]]}}, -{"type":"Feature","id":"48241","properties":{"name":"Jasper"},"geometry":{"type":"Polygon","coordinates":[[[-93.997348,31.139937],[-93.909717,31.156367],[-93.898763,30.241718],[-94.117841,30.241718],[-94.074025,30.526519],[-94.29858,31.035875],[-94.457411,31.035875],[-94.128795,31.101598],[-94.041164,31.13446],[-93.997348,31.139937]]]}}, -{"type":"Feature","id":"48243","properties":{"name":"Jeff Davis"},"geometry":{"type":"Polygon","coordinates":[[[-104.102303,31.107075],[-103.587471,30.767505],[-103.439593,30.663443],[-103.801071,30.411504],[-104.98409,30.630581],[-104.918367,30.663443],[-104.102303,31.107075]]]}}, -{"type":"Feature","id":"48245","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-94.216426,30.175995],[-94.117841,30.159564],[-93.854948,29.863809],[-93.838517,29.688547],[-94.353349,29.562578],[-94.44098,29.891194],[-94.446457,30.110272],[-94.216426,30.175995]]]}}, -{"type":"Feature","id":"48247","properties":{"name":"Jim Hogg"},"geometry":{"type":"Polygon","coordinates":[[[-98.521301,27.26774],[-98.422716,26.785769],[-98.953979,26.785769],[-98.953979,27.26774],[-98.800625,27.355371],[-98.521301,27.26774]]]}}, -{"type":"Feature","id":"48249","properties":{"name":"Jim Wells"},"geometry":{"type":"Polygon","coordinates":[[[-98.2365,28.056419],[-97.880499,28.056419],[-97.798345,27.996173],[-97.940745,27.634695],[-98.011945,27.634695],[-98.055761,27.262263],[-98.231023,27.262263],[-98.2365,28.056419]]]}}, -{"type":"Feature","id":"48251","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-97.551882,32.552987],[-97.086342,32.54751],[-97.086342,32.268186],[-97.113727,32.257232],[-97.475205,32.175078],[-97.617606,32.202463],[-97.617606,32.317479],[-97.617606,32.552987],[-97.551882,32.552987]]]}}, -{"type":"Feature","id":"48253","properties":{"name":"Jones"},"geometry":{"type":"Polygon","coordinates":[[[-100.109614,32.958281],[-99.989121,32.958281],[-99.611212,32.958281],[-99.611212,32.514649],[-99.627643,32.514649],[-100.136998,32.520126],[-100.147952,32.520126],[-100.142475,32.958281],[-100.109614,32.958281]]]}}, -{"type":"Feature","id":"48255","properties":{"name":"Karnes"},"geometry":{"type":"Polygon","coordinates":[[[-97.727145,29.223007],[-97.612129,29.107992],[-97.57379,28.812237],[-97.776437,28.669836],[-97.935268,28.713652],[-98.006468,28.691744],[-98.099576,28.784852],[-98.192684,28.883437],[-97.727145,29.223007]]]}}, -{"type":"Feature","id":"48257","properties":{"name":"Kaufman"},"geometry":{"type":"Polygon","coordinates":[[[-96.297663,32.843265],[-96.078585,32.837788],[-96.078585,32.355817],[-96.215509,32.361294],[-96.451017,32.361294],[-96.527695,32.54751],[-96.516741,32.81588],[-96.297663,32.843265]]]}}, -{"type":"Feature","id":"48259","properties":{"name":"Kendall"},"geometry":{"type":"Polygon","coordinates":[[[-98.921118,30.137656],[-98.587024,30.137656],[-98.411762,29.93501],[-98.64727,29.743317],[-98.778717,29.721409],[-98.915641,29.781655],[-98.921118,30.137656]]]}}, -{"type":"Feature","id":"48261","properties":{"name":"Kenedy"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-97.738098,27.273217],[-97.634037,27.284171],[-97.442344,26.599553],[-97.655944,26.599553],[-97.957176,26.610507],[-97.984561,26.780292],[-97.984561,27.207493],[-97.738098,27.273217]]],[[[-97.371143,27.278694],[-97.349236,27.278694],[-97.288989,26.599553],[-97.316374,26.599553],[-97.371143,27.278694]]]]}}, -{"type":"Feature","id":"48263","properties":{"name":"Kent"},"geometry":{"type":"Polygon","coordinates":[[[-100.816139,33.396436],[-100.514907,33.396436],[-100.520384,32.963758],[-100.657308,32.963758],[-101.040693,32.969235],[-101.040693,33.396436],[-100.816139,33.396436]]]}}, -{"type":"Feature","id":"48265","properties":{"name":"Kerr"},"geometry":{"type":"Polygon","coordinates":[[[-99.605735,30.291011],[-99.304503,30.285534],[-98.921118,30.137656],[-98.915641,29.781655],[-99.600258,29.907625],[-99.759089,30.071933],[-99.753612,30.291011],[-99.605735,30.291011]]]}}, -{"type":"Feature","id":"48267","properties":{"name":"Kimble"},"geometry":{"type":"Polygon","coordinates":[[[-99.759089,30.712735],[-99.485242,30.712735],[-99.304503,30.499135],[-99.304503,30.285534],[-99.605735,30.291011],[-99.753612,30.291011],[-100.115091,30.291011],[-100.115091,30.712735],[-99.759089,30.712735]]]}}, -{"type":"Feature","id":"48269","properties":{"name":"King"},"geometry":{"type":"Polygon","coordinates":[[[-99.994598,33.834591],[-99.989121,33.396436],[-100.197245,33.396436],[-100.514907,33.396436],[-100.520384,33.834591],[-100.049367,33.834591],[-99.994598,33.834591]]]}}, -{"type":"Feature","id":"48271","properties":{"name":"Kinney"},"geometry":{"type":"Polygon","coordinates":[[[-100.575153,29.622824],[-100.109614,29.622824],[-100.109614,29.086084],[-100.668261,29.086084],[-100.794231,29.239438],[-100.701123,29.622824],[-100.575153,29.622824]]]}}, -{"type":"Feature","id":"48273","properties":{"name":"Kleberg"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-98.011945,27.634695],[-97.940745,27.634695],[-97.327328,27.563495],[-97.634037,27.284171],[-97.738098,27.273217],[-97.984561,27.207493],[-98.055761,27.262263],[-98.011945,27.634695]]],[[[-97.245174,27.579925],[-97.223266,27.574448],[-97.349236,27.278694],[-97.371143,27.278694],[-97.245174,27.579925]]]]}}, -{"type":"Feature","id":"48275","properties":{"name":"Knox"},"geometry":{"type":"Polygon","coordinates":[[[-99.868628,33.834591],[-99.474288,33.736006],[-99.474288,33.396436],[-99.518104,33.396436],[-99.989121,33.396436],[-99.994598,33.834591],[-99.868628,33.834591]]]}}, -{"type":"Feature","id":"48277","properties":{"name":"Lamar"},"geometry":{"type":"Polygon","coordinates":[[[-95.311814,33.878407],[-95.306337,33.380005],[-95.651384,33.484067],[-95.859508,33.462159],[-95.843077,33.840068],[-95.760923,33.87293],[-95.311814,33.878407]]]}}, -{"type":"Feature","id":"48279","properties":{"name":"Lamb"},"geometry":{"type":"Polygon","coordinates":[[[-102.327774,34.311085],[-102.092266,34.311085],[-102.086789,33.823637],[-102.618052,33.823637],[-102.612575,34.311085],[-102.524944,34.311085],[-102.327774,34.311085]]]}}, -{"type":"Feature","id":"48281","properties":{"name":"Lampasas"},"geometry":{"type":"Polygon","coordinates":[[[-98.181731,31.463076],[-97.907884,31.068736],[-97.91336,31.035875],[-98.017422,31.035875],[-98.439147,31.030398],[-98.565116,31.233045],[-98.269362,31.413784],[-98.181731,31.463076]]]}}, -{"type":"Feature","id":"48283","properties":{"name":"La Salle"},"geometry":{"type":"Polygon","coordinates":[[[-98.800625,28.647929],[-98.800625,28.636975],[-98.800625,28.056419],[-99.392134,28.204297],[-99.397611,28.642452],[-98.800625,28.647929]]]}}, -{"type":"Feature","id":"48285","properties":{"name":"Lavaca"},"geometry":{"type":"Polygon","coordinates":[[[-96.872742,29.633778],[-96.659141,29.261346],[-96.938465,29.064176],[-96.976804,29.102515],[-97.239697,29.381839],[-97.141112,29.628301],[-96.872742,29.633778]]]}}, -{"type":"Feature","id":"48287","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-97.157543,30.455319],[-96.96585,30.559381],[-96.64271,30.296488],[-96.796065,30.159564],[-96.801542,30.154087],[-97.026096,30.050025],[-97.332805,30.40055],[-97.157543,30.455319]]]}}, -{"type":"Feature","id":"48289","properties":{"name":"Leon"},"geometry":{"type":"Polygon","coordinates":[[[-95.728061,31.643815],[-95.739015,31.501415],[-95.7664,31.096121],[-95.903323,31.090644],[-96.242894,30.975628],[-96.319571,31.359014],[-96.237417,31.413784],[-95.788308,31.61643],[-95.728061,31.643815]]]}}, -{"type":"Feature","id":"48291","properties":{"name":"Liberty"},"geometry":{"type":"Polygon","coordinates":[[[-94.851751,30.493658],[-94.731258,30.488181],[-94.446457,30.110272],[-94.44098,29.891194],[-94.97772,29.885717],[-95.098213,30.165041],[-95.163936,30.34578],[-94.851751,30.493658]]]}}, -{"type":"Feature","id":"48293","properties":{"name":"Limestone"},"geometry":{"type":"Polygon","coordinates":[[[-96.719387,31.8136],[-96.494833,31.797169],[-96.237417,31.413784],[-96.319571,31.359014],[-96.598895,31.222091],[-96.801542,31.523322],[-96.932988,31.709538],[-96.719387,31.8136]]]}}, -{"type":"Feature","id":"48295","properties":{"name":"Lipscomb"},"geometry":{"type":"Polygon","coordinates":[[[-100.005552,36.501861],[-100.000075,36.058229],[-100.542292,36.058229],[-100.547769,36.058229],[-100.547769,36.501861],[-100.005552,36.501861]]]}}, -{"type":"Feature","id":"48297","properties":{"name":"Live Oak"},"geometry":{"type":"Polygon","coordinates":[[[-98.099576,28.784852],[-98.006468,28.691744],[-97.820252,28.176912],[-97.880499,28.056419],[-98.2365,28.056419],[-98.335085,28.056419],[-98.335085,28.615067],[-98.099576,28.784852]]]}}, -{"type":"Feature","id":"48299","properties":{"name":"Llano"},"geometry":{"type":"Polygon","coordinates":[[[-98.515824,30.920859],[-98.444624,30.920859],[-98.351516,30.488181],[-98.411762,30.504611],[-98.592501,30.499135],[-98.964933,30.499135],[-98.964933,30.920859],[-98.515824,30.920859]]]}}, -{"type":"Feature","id":"48301","properties":{"name":"Loving"},"geometry":{"type":"Polygon","coordinates":[[[-103.71344,31.999816],[-103.324578,31.999816],[-103.330055,31.649292],[-103.609378,31.649292],[-103.98181,31.999816],[-103.724394,31.999816],[-103.71344,31.999816]]]}}, -{"type":"Feature","id":"48303","properties":{"name":"Lubbock"},"geometry":{"type":"Polygon","coordinates":[[[-101.571957,33.829114],[-101.561003,33.829114],[-101.555526,33.396436],[-102.075835,33.390959],[-102.086789,33.823637],[-101.571957,33.829114]]]}}, -{"type":"Feature","id":"48305","properties":{"name":"Lynn"},"geometry":{"type":"Polygon","coordinates":[[[-101.555526,33.396436],[-101.555526,32.963758],[-101.692449,32.963758],[-102.075835,32.958281],[-102.075835,33.390959],[-101.555526,33.396436]]]}}, -{"type":"Feature","id":"48307","properties":{"name":"McCulloch"},"geometry":{"type":"Polygon","coordinates":[[[-99.430473,31.468553],[-99.200441,31.468553],[-99.090903,31.463076],[-99.090903,30.942767],[-99.485242,30.942767],[-99.605735,31.085167],[-99.600258,31.490461],[-99.430473,31.468553]]]}}, -{"type":"Feature","id":"48309","properties":{"name":"McLennan"},"geometry":{"type":"Polygon","coordinates":[[[-97.080866,31.840985],[-96.932988,31.709538],[-96.801542,31.523322],[-97.278035,31.282337],[-97.404005,31.304245],[-97.420436,31.320676],[-97.606652,31.589046],[-97.278035,31.747877],[-97.080866,31.840985]]]}}, -{"type":"Feature","id":"48311","properties":{"name":"McMullen"},"geometry":{"type":"Polygon","coordinates":[[[-98.581547,28.642452],[-98.335085,28.615067],[-98.335085,28.056419],[-98.800625,28.056419],[-98.800625,28.636975],[-98.581547,28.642452]]]}}, -{"type":"Feature","id":"48313","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-95.903323,31.090644],[-95.7664,31.096121],[-95.618522,30.931813],[-95.864985,30.86609],[-96.166217,30.822274],[-96.237417,30.964674],[-96.242894,30.975628],[-95.903323,31.090644]]]}}, -{"type":"Feature","id":"48315","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-94.249287,32.881604],[-94.041164,32.881604],[-94.041164,32.695388],[-94.703873,32.793973],[-94.703873,32.881604],[-94.654581,32.881604],[-94.249287,32.881604]]]}}, -{"type":"Feature","id":"48317","properties":{"name":"Martin"},"geometry":{"type":"Polygon","coordinates":[[[-101.686972,32.525602],[-101.692449,32.087447],[-101.747219,32.087447],[-101.774603,32.087447],[-101.933435,32.087447],[-102.212759,32.087447],[-102.212759,32.525602],[-102.201805,32.525602],[-101.686972,32.525602]]]}}, -{"type":"Feature","id":"48319","properties":{"name":"Mason"},"geometry":{"type":"Polygon","coordinates":[[[-99.485242,30.942767],[-99.090903,30.942767],[-98.964933,30.920859],[-98.964933,30.499135],[-99.304503,30.499135],[-99.485242,30.712735],[-99.485242,30.942767]]]}}, -{"type":"Feature","id":"48321","properties":{"name":"Matagorda"},"geometry":{"type":"Polygon","coordinates":[[[-95.864985,29.223007],[-95.508984,28.823191],[-96.379817,28.385036],[-96.37434,28.401466],[-96.325048,28.642452],[-96.325048,28.675313],[-96.308617,28.965591],[-95.875939,29.228484],[-95.864985,29.223007]]]}}, -{"type":"Feature","id":"48323","properties":{"name":"Maverick"},"geometry":{"type":"Polygon","coordinates":[[[-100.109614,29.086084],[-100.115091,28.647929],[-100.115091,28.19882],[-100.213675,28.19882],[-100.668261,29.086084],[-100.109614,29.086084]]]}}, -{"type":"Feature","id":"48325","properties":{"name":"Medina"},"geometry":{"type":"Polygon","coordinates":[[[-98.806102,29.688547],[-98.806102,29.250392],[-98.806102,29.091561],[-98.904687,29.091561],[-99.414042,29.091561],[-99.414042,29.628301],[-98.806102,29.688547]]]}}, -{"type":"Feature","id":"48327","properties":{"name":"Menard"},"geometry":{"type":"Polygon","coordinates":[[[-100.115091,31.090644],[-99.605735,31.085167],[-99.485242,30.942767],[-99.485242,30.712735],[-99.759089,30.712735],[-100.115091,30.712735],[-100.115091,31.090644]]]}}, -{"type":"Feature","id":"48329","properties":{"name":"Midland"},"geometry":{"type":"Polygon","coordinates":[[[-101.933435,32.087447],[-101.774603,32.087447],[-101.774603,31.649292],[-102.223713,31.649292],[-102.289436,31.649292],[-102.289436,32.087447],[-102.212759,32.087447],[-101.933435,32.087447]]]}}, -{"type":"Feature","id":"48331","properties":{"name":"Milam"},"geometry":{"type":"Polygon","coordinates":[[[-96.828926,31.107075],[-96.620803,30.729166],[-96.96585,30.559381],[-97.157543,30.455319],[-97.316374,30.751074],[-97.069912,30.986582],[-96.828926,31.107075]]]}}, -{"type":"Feature","id":"48333","properties":{"name":"Mills"},"geometry":{"type":"Polygon","coordinates":[[[-98.669178,31.698584],[-98.461055,31.682154],[-98.269362,31.413784],[-98.565116,31.233045],[-98.992318,31.484984],[-98.669178,31.698584]]]}}, -{"type":"Feature","id":"48335","properties":{"name":"Mitchell"},"geometry":{"type":"Polygon","coordinates":[[[-100.662785,32.525602],[-100.662785,32.087447],[-100.821616,32.087447],[-101.183094,32.087447],[-101.17214,32.525602],[-101.17214,32.525602],[-100.662785,32.525602]]]}}, -{"type":"Feature","id":"48337","properties":{"name":"Montague"},"geometry":{"type":"Polygon","coordinates":[[[-97.562836,33.894838],[-97.486159,33.916745],[-97.486159,33.434775],[-97.50259,33.434775],[-97.918837,33.434775],[-97.979084,33.467636],[-97.979084,33.889361],[-97.562836,33.894838]]]}}, -{"type":"Feature","id":"48339","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-95.832123,30.630581],[-95.361106,30.504611],[-95.163936,30.34578],[-95.098213,30.165041],[-95.218706,30.066456],[-95.804738,30.088364],[-95.804738,30.247195],[-95.832123,30.630581]]]}}, -{"type":"Feature","id":"48341","properties":{"name":"Moore"},"geometry":{"type":"Polygon","coordinates":[[[-102.125128,36.058229],[-101.621249,36.052752],[-101.621249,35.625551],[-101.621249,35.620074],[-101.659588,35.620074],[-102.163466,35.620074],[-102.163466,35.625551],[-102.163466,36.052752],[-102.125128,36.058229]]]}}, -{"type":"Feature","id":"48343","properties":{"name":"Morris"},"geometry":{"type":"Polygon","coordinates":[[[-94.807935,33.363574],[-94.747689,33.330713],[-94.654581,33.270466],[-94.654581,32.881604],[-94.703873,32.881604],[-94.720304,32.903511],[-94.818889,32.980189],[-94.807935,33.363574]]]}}, -{"type":"Feature","id":"48345","properties":{"name":"Motley"},"geometry":{"type":"Polygon","coordinates":[[[-100.673738,34.311085],[-100.514907,34.316562],[-100.520384,33.834591],[-100.90377,33.834591],[-101.040693,33.834591],[-101.040693,34.311085],[-100.947585,34.311085],[-100.673738,34.311085]]]}}, -{"type":"Feature","id":"48347","properties":{"name":"Nacogdoches"},"geometry":{"type":"Polygon","coordinates":[[[-94.512181,31.846462],[-94.451934,31.846462],[-94.397165,31.654769],[-94.325965,31.222091],[-94.868182,31.528799],[-94.939382,31.846462],[-94.512181,31.846462]]]}}, -{"type":"Feature","id":"48349","properties":{"name":"Navarro"},"geometry":{"type":"Polygon","coordinates":[[[-96.385294,32.328433],[-96.056678,32.01077],[-96.494833,31.797169],[-96.719387,31.8136],[-96.89465,32.076493],[-96.385294,32.328433]]]}}, -{"type":"Feature","id":"48351","properties":{"name":"Newton"},"geometry":{"type":"Polygon","coordinates":[[[-93.603008,31.178275],[-93.553716,31.183752],[-93.559193,30.86609],[-93.739932,30.40055],[-93.70707,30.247195],[-93.898763,30.241718],[-93.909717,31.156367],[-93.603008,31.178275]]]}}, -{"type":"Feature","id":"48353","properties":{"name":"Nolan"},"geometry":{"type":"Polygon","coordinates":[[[-100.147952,32.520126],[-100.153429,32.08197],[-100.235583,32.08197],[-100.662785,32.087447],[-100.662785,32.525602],[-100.147952,32.520126]]]}}, -{"type":"Feature","id":"48355","properties":{"name":"Nueces"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-97.803822,27.979742],[-97.365666,27.848295],[-97.327328,27.563495],[-97.940745,27.634695],[-97.798345,27.996173],[-97.803822,27.979742]]],[[[-97.053481,27.842818],[-97.048004,27.837342],[-97.223266,27.574448],[-97.245174,27.579925],[-97.053481,27.842818]]]]}}, -{"type":"Feature","id":"48357","properties":{"name":"Ochiltree"},"geometry":{"type":"Polygon","coordinates":[[[-100.805185,36.501861],[-100.547769,36.501861],[-100.547769,36.058229],[-100.947585,36.058229],[-101.084509,36.058229],[-101.084509,36.501861],[-100.953062,36.501861],[-100.805185,36.501861]]]}}, -{"type":"Feature","id":"48359","properties":{"name":"Oldham"},"geometry":{"type":"Polygon","coordinates":[[[-102.163466,35.625551],[-102.163466,35.620074],[-102.168943,35.181919],[-102.579714,35.187396],[-103.039777,35.181919],[-103.039777,35.620074],[-102.163466,35.625551]]]}}, -{"type":"Feature","id":"48361","properties":{"name":"Orange"},"geometry":{"type":"Polygon","coordinates":[[[-93.70707,30.247195],[-93.723501,30.050025],[-93.854948,29.863809],[-94.117841,30.159564],[-94.117841,30.241718],[-93.898763,30.241718],[-93.70707,30.247195]]]}}, -{"type":"Feature","id":"48363","properties":{"name":"Palo Pinto"},"geometry":{"type":"Polygon","coordinates":[[[-98.428193,33.007573],[-98.055761,33.002096],[-98.066715,32.558464],[-98.066715,32.509172],[-98.477485,32.514649],[-98.57607,32.514649],[-98.57607,32.952804],[-98.428193,33.007573]]]}}, -{"type":"Feature","id":"48365","properties":{"name":"Panola"},"geometry":{"type":"Polygon","coordinates":[[[-94.462888,32.377725],[-94.041164,32.394156],[-94.041164,32.196986],[-94.013779,31.977908],[-94.134272,31.977908],[-94.512181,31.972432],[-94.490273,32.394156],[-94.462888,32.377725]]]}}, -{"type":"Feature","id":"48367","properties":{"name":"Parker"},"geometry":{"type":"Polygon","coordinates":[[[-98.055761,33.002096],[-97.924314,33.002096],[-97.546405,32.996619],[-97.551882,32.552987],[-97.617606,32.552987],[-98.066715,32.558464],[-98.055761,33.002096],[-98.055761,33.002096]]]}}, -{"type":"Feature","id":"48369","properties":{"name":"Parmer"},"geometry":{"type":"Polygon","coordinates":[[[-103.045254,34.74924],[-102.524944,34.74924],[-102.524944,34.311085],[-102.612575,34.311085],[-103.045254,34.311085],[-103.045254,34.74924]]]}}, -{"type":"Feature","id":"48371","properties":{"name":"Pecos"},"geometry":{"type":"Polygon","coordinates":[[[-102.83713,31.282337],[-102.76593,31.293291],[-102.388021,31.085167],[-101.769126,30.652489],[-102.344205,30.597719],[-102.56876,30.050025],[-103.346485,30.603196],[-103.439593,30.663443],[-103.587471,30.767505],[-103.012392,31.369968],[-102.83713,31.282337]]]}}, -{"type":"Feature","id":"48373","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-94.813412,31.13446],[-94.561473,31.057782],[-94.545042,30.526519],[-94.731258,30.488181],[-94.851751,30.493658],[-95.202275,30.822274],[-94.840797,31.145414],[-94.813412,31.13446]]]}}, -{"type":"Feature","id":"48375","properties":{"name":"Potter"},"geometry":{"type":"Polygon","coordinates":[[[-101.659588,35.620074],[-101.621249,35.620074],[-101.621249,35.181919],[-101.988204,35.181919],[-102.168943,35.181919],[-102.163466,35.620074],[-101.659588,35.620074]]]}}, -{"type":"Feature","id":"48377","properties":{"name":"Presidio"},"geometry":{"type":"Polygon","coordinates":[[[-104.98409,30.630581],[-103.801071,30.411504],[-103.790117,29.261346],[-104.507597,29.639255],[-104.98409,30.630581],[-104.98409,30.630581]]]}}, -{"type":"Feature","id":"48379","properties":{"name":"Rains"},"geometry":{"type":"Polygon","coordinates":[[[-95.864985,32.980189],[-95.667815,32.958281],[-95.634953,32.722772],[-95.936185,32.837788],[-95.864985,32.980189]]]}}, -{"type":"Feature","id":"48381","properties":{"name":"Randall"},"geometry":{"type":"Polygon","coordinates":[[[-101.988204,35.181919],[-101.621249,35.181919],[-101.626726,34.74924],[-101.999158,34.74924],[-102.004635,34.74924],[-102.168943,34.74924],[-102.168943,35.181919],[-101.988204,35.181919]]]}}, -{"type":"Feature","id":"48383","properties":{"name":"Reagan"},"geometry":{"type":"Polygon","coordinates":[[[-101.686972,31.649292],[-101.265248,31.649292],[-101.265248,31.556184],[-101.265248,31.528799],[-101.276202,31.07969],[-101.774603,31.07969],[-101.774603,31.649292],[-101.686972,31.649292]]]}}, -{"type":"Feature","id":"48385","properties":{"name":"Real"},"geometry":{"type":"Polygon","coordinates":[[[-99.759089,30.071933],[-99.600258,29.907625],[-99.605735,29.628301],[-100.016506,29.622824],[-99.759089,30.071933]]]}}, -{"type":"Feature","id":"48387","properties":{"name":"Red River"},"geometry":{"type":"Polygon","coordinates":[[[-95.158459,33.938653],[-94.736735,33.703145],[-94.747689,33.330713],[-94.807935,33.363574],[-95.125598,33.390959],[-95.306337,33.380005],[-95.306337,33.380005],[-95.311814,33.878407],[-95.158459,33.938653]]]}}, -{"type":"Feature","id":"48389","properties":{"name":"Reeves"},"geometry":{"type":"Polygon","coordinates":[[[-104.025626,31.999816],[-103.98181,31.999816],[-103.609378,31.649292],[-103.012392,31.369968],[-103.587471,30.767505],[-104.102303,31.107075],[-104.025626,31.999816]]]}}, -{"type":"Feature","id":"48391","properties":{"name":"Refugio"},"geometry":{"type":"Polygon","coordinates":[[[-97.146589,28.549344],[-96.889173,28.505528],[-96.763203,28.41242],[-96.790588,28.319312],[-97.261605,28.078327],[-97.540929,28.165958],[-97.37662,28.390513],[-97.16302,28.554821],[-97.146589,28.549344]]]}}, -{"type":"Feature","id":"48393","properties":{"name":"Roberts"},"geometry":{"type":"Polygon","coordinates":[[[-100.947585,36.058229],[-100.547769,36.058229],[-100.542292,36.058229],[-100.542292,35.620074],[-101.084509,35.620074],[-101.084509,35.625551],[-101.084509,35.625551],[-101.084509,36.052752],[-101.084509,36.058229],[-100.947585,36.058229]]]}}, -{"type":"Feature","id":"48395","properties":{"name":"Robertson"},"geometry":{"type":"Polygon","coordinates":[[[-96.319571,31.359014],[-96.242894,30.975628],[-96.566033,30.696304],[-96.620803,30.729166],[-96.828926,31.107075],[-96.598895,31.222091],[-96.319571,31.359014]]]}}, -{"type":"Feature","id":"48397","properties":{"name":"Rockwall"},"geometry":{"type":"Polygon","coordinates":[[[-96.440064,32.980189],[-96.297663,32.980189],[-96.297663,32.843265],[-96.516741,32.81588],[-96.516741,32.980189],[-96.440064,32.980189]]]}}, -{"type":"Feature","id":"48399","properties":{"name":"Runnels"},"geometry":{"type":"Polygon","coordinates":[[[-100.054844,32.08197],[-99.715274,32.08197],[-99.720751,31.578092],[-99.726228,31.578092],[-100.109614,31.578092],[-100.235583,31.693108],[-100.235583,32.08197],[-100.153429,32.08197],[-100.054844,32.08197]]]}}, -{"type":"Feature","id":"48401","properties":{"name":"Rusk"},"geometry":{"type":"Polygon","coordinates":[[[-94.577904,32.394156],[-94.490273,32.394156],[-94.512181,31.972432],[-94.451934,31.846462],[-94.512181,31.846462],[-94.939382,31.846462],[-94.983197,32.13674],[-94.988674,32.366771],[-94.577904,32.394156]]]}}, -{"type":"Feature","id":"48403","properties":{"name":"Sabine"},"geometry":{"type":"Polygon","coordinates":[[[-93.843994,31.589046],[-93.83304,31.583569],[-93.603008,31.178275],[-93.909717,31.156367],[-93.997348,31.139937],[-94.041164,31.13446],[-93.986394,31.567138],[-93.843994,31.589046]]]}}, -{"type":"Feature","id":"48405","properties":{"name":"San Augustine"},"geometry":{"type":"Polygon","coordinates":[[[-94.002825,31.578092],[-93.986394,31.567138],[-94.041164,31.13446],[-94.128795,31.101598],[-94.325965,31.222091],[-94.397165,31.654769],[-94.002825,31.578092]]]}}, -{"type":"Feature","id":"48407","properties":{"name":"San Jacinto"},"geometry":{"type":"Polygon","coordinates":[[[-95.311814,30.88252],[-95.202275,30.822274],[-94.851751,30.493658],[-95.163936,30.34578],[-95.361106,30.504611],[-95.328245,30.860613],[-95.311814,30.88252]]]}}, -{"type":"Feature","id":"48409","properties":{"name":"San Patricio"},"geometry":{"type":"Polygon","coordinates":[[[-97.820252,28.176912],[-97.540929,28.165958],[-97.261605,28.078327],[-97.135635,27.903065],[-97.365666,27.848295],[-97.803822,27.979742],[-97.798345,27.996173],[-97.880499,28.056419],[-97.820252,28.176912]]]}}, -{"type":"Feature","id":"48411","properties":{"name":"San Saba"},"geometry":{"type":"Polygon","coordinates":[[[-98.992318,31.484984],[-98.565116,31.233045],[-98.439147,31.030398],[-98.444624,30.920859],[-98.515824,30.920859],[-98.964933,30.920859],[-99.090903,30.942767],[-99.090903,31.463076],[-98.992318,31.484984]]]}}, -{"type":"Feature","id":"48413","properties":{"name":"Schleicher"},"geometry":{"type":"Polygon","coordinates":[[[-100.690169,31.085167],[-100.115091,31.090644],[-100.115091,30.712735],[-100.958539,30.707258],[-100.964016,31.085167],[-100.690169,31.085167]]]}}, -{"type":"Feature","id":"48415","properties":{"name":"Scurry"},"geometry":{"type":"Polygon","coordinates":[[[-101.040693,32.969235],[-100.657308,32.963758],[-100.662785,32.525602],[-101.17214,32.525602],[-101.17214,32.963758],[-101.040693,32.969235]]]}}, -{"type":"Feature","id":"48417","properties":{"name":"Shackelford"},"geometry":{"type":"Polygon","coordinates":[[[-99.233303,32.958281],[-99.09638,32.958281],[-99.09638,32.514649],[-99.11281,32.514649],[-99.194965,32.514649],[-99.611212,32.514649],[-99.611212,32.958281],[-99.468812,32.958281],[-99.233303,32.958281]]]}}, -{"type":"Feature","id":"48419","properties":{"name":"Shelby"},"geometry":{"type":"Polygon","coordinates":[[[-94.134272,31.977908],[-94.013779,31.977908],[-93.882332,31.846462],[-93.83304,31.583569],[-93.843994,31.589046],[-93.986394,31.567138],[-94.002825,31.578092],[-94.397165,31.654769],[-94.451934,31.846462],[-94.512181,31.972432],[-94.134272,31.977908]]]}}, -{"type":"Feature","id":"48421","properties":{"name":"Sherman"},"geometry":{"type":"Polygon","coordinates":[[[-101.812942,36.501861],[-101.621249,36.501861],[-101.621249,36.052752],[-102.125128,36.058229],[-102.163466,36.052752],[-102.163466,36.501861],[-102.03202,36.501861],[-101.812942,36.501861]]]}}, -{"type":"Feature","id":"48423","properties":{"name":"Smith"},"geometry":{"type":"Polygon","coordinates":[[[-95.574707,32.67348],[-95.152983,32.569418],[-94.988674,32.536556],[-94.988674,32.366771],[-94.983197,32.13674],[-95.459691,32.13674],[-95.448737,32.355817],[-95.596615,32.684434],[-95.574707,32.67348]]]}}, -{"type":"Feature","id":"48425","properties":{"name":"Somervell"},"geometry":{"type":"Polygon","coordinates":[[[-97.946222,32.235325],[-97.617606,32.317479],[-97.617606,32.202463],[-97.62856,32.20794],[-97.864068,32.087447],[-97.946222,32.235325]]]}}, -{"type":"Feature","id":"48427","properties":{"name":"Starr"},"geometry":{"type":"Polygon","coordinates":[[[-98.953979,26.785769],[-98.422716,26.785769],[-98.318654,26.785769],[-98.587024,26.254506],[-99.16758,26.572168],[-98.953979,26.785769]]]}}, -{"type":"Feature","id":"48429","properties":{"name":"Stephens"},"geometry":{"type":"Polygon","coordinates":[[[-98.762286,32.958281],[-98.57607,32.952804],[-98.57607,32.514649],[-98.740378,32.514649],[-99.09638,32.514649],[-99.09638,32.958281],[-98.948502,32.958281],[-98.762286,32.958281]]]}}, -{"type":"Feature","id":"48431","properties":{"name":"Sterling"},"geometry":{"type":"Polygon","coordinates":[[[-101.265248,32.087447],[-101.183094,32.087447],[-100.821616,32.087447],[-100.827093,31.698584],[-101.265248,31.556184],[-101.265248,31.649292],[-101.265248,32.087447]]]}}, -{"type":"Feature","id":"48433","properties":{"name":"Stonewall"},"geometry":{"type":"Polygon","coordinates":[[[-100.197245,33.396436],[-99.989121,33.396436],[-99.989121,32.958281],[-100.109614,32.958281],[-100.142475,32.958281],[-100.520384,32.963758],[-100.514907,33.396436],[-100.197245,33.396436]]]}}, -{"type":"Feature","id":"48435","properties":{"name":"Sutton"},"geometry":{"type":"Polygon","coordinates":[[[-100.115091,30.712735],[-100.115091,30.291011],[-100.701123,30.291011],[-100.958539,30.285534],[-100.958539,30.707258],[-100.115091,30.712735]]]}}, -{"type":"Feature","id":"48437","properties":{"name":"Swisher"},"geometry":{"type":"Polygon","coordinates":[[[-101.999158,34.74924],[-101.626726,34.74924],[-101.473372,34.74924],[-101.473372,34.311085],[-101.56648,34.311085],[-101.999158,34.311085],[-101.999158,34.74924]]]}}, -{"type":"Feature","id":"48439","properties":{"name":"Tarrant"},"geometry":{"type":"Polygon","coordinates":[[[-97.535452,32.996619],[-97.398528,32.991142],[-97.031573,32.985665],[-97.03705,32.54751],[-97.086342,32.54751],[-97.551882,32.552987],[-97.546405,32.996619],[-97.535452,32.996619]]]}}, -{"type":"Feature","id":"48441","properties":{"name":"Taylor"},"geometry":{"type":"Polygon","coordinates":[[[-100.136998,32.520126],[-99.627643,32.514649],[-99.63312,32.08197],[-99.715274,32.08197],[-100.054844,32.08197],[-100.153429,32.08197],[-100.147952,32.520126],[-100.136998,32.520126]]]}}, -{"type":"Feature","id":"48443","properties":{"name":"Terrell"},"geometry":{"type":"Polygon","coordinates":[[[-102.56876,30.050025],[-102.344205,30.597719],[-101.769126,30.652489],[-101.758173,30.285534],[-101.76365,29.781655],[-102.322297,29.88024],[-102.56876,30.050025]]]}}, -{"type":"Feature","id":"48445","properties":{"name":"Terry"},"geometry":{"type":"Polygon","coordinates":[[[-102.366113,33.390959],[-102.075835,33.390959],[-102.075835,32.958281],[-102.207282,32.958281],[-102.596144,32.958281],[-102.596144,33.390959],[-102.366113,33.390959]]]}}, -{"type":"Feature","id":"48447","properties":{"name":"Throckmorton"},"geometry":{"type":"Polygon","coordinates":[[[-99.474288,33.396436],[-98.953979,33.396436],[-98.948502,32.958281],[-99.09638,32.958281],[-99.233303,32.958281],[-99.468812,32.958281],[-99.474288,33.396436]]]}}, -{"type":"Feature","id":"48449","properties":{"name":"Titus"},"geometry":{"type":"Polygon","coordinates":[[[-94.807935,33.363574],[-94.818889,32.980189],[-95.125598,33.034958],[-95.125598,33.390959],[-94.807935,33.363574]]]}}, -{"type":"Feature","id":"48451","properties":{"name":"Tom Green"},"geometry":{"type":"Polygon","coordinates":[[[-100.827093,31.698584],[-100.235583,31.693108],[-100.109614,31.578092],[-100.115091,31.090644],[-100.690169,31.085167],[-100.695646,31.523322],[-101.265248,31.528799],[-101.265248,31.556184],[-100.827093,31.698584]]]}}, -{"type":"Feature","id":"48453","properties":{"name":"Travis"},"geometry":{"type":"Polygon","coordinates":[[[-97.973607,30.625104],[-97.371143,30.41698],[-97.650467,30.071933],[-97.666898,30.066456],[-97.710714,30.022641],[-98.170777,30.356734],[-98.126961,30.427934],[-98.050284,30.625104],[-97.973607,30.625104]]]}}, -{"type":"Feature","id":"48455","properties":{"name":"Trinity"},"geometry":{"type":"Polygon","coordinates":[[[-94.950336,31.342583],[-94.840797,31.145414],[-95.202275,30.822274],[-95.311814,30.88252],[-95.328245,30.860613],[-95.432306,31.057782],[-94.955813,31.386399],[-94.950336,31.342583]]]}}, -{"type":"Feature","id":"48457","properties":{"name":"Tyler"},"geometry":{"type":"Polygon","coordinates":[[[-94.29858,31.035875],[-94.074025,30.526519],[-94.44098,30.526519],[-94.545042,30.526519],[-94.561473,31.057782],[-94.457411,31.035875],[-94.29858,31.035875]]]}}, -{"type":"Feature","id":"48459","properties":{"name":"Upshur"},"geometry":{"type":"Polygon","coordinates":[[[-94.780551,32.903511],[-94.720304,32.903511],[-94.703873,32.881604],[-94.703873,32.793973],[-94.703873,32.651572],[-94.988674,32.536556],[-95.152983,32.569418],[-95.152983,32.903511],[-94.780551,32.903511]]]}}, -{"type":"Feature","id":"48461","properties":{"name":"Upton"},"geometry":{"type":"Polygon","coordinates":[[[-102.223713,31.649292],[-101.774603,31.649292],[-101.774603,31.07969],[-102.30039,31.085167],[-102.316821,31.649292],[-102.289436,31.649292],[-102.223713,31.649292]]]}}, -{"type":"Feature","id":"48463","properties":{"name":"Uvalde"},"geometry":{"type":"Polygon","coordinates":[[[-99.605735,29.628301],[-99.414042,29.628301],[-99.414042,29.091561],[-100.109614,29.086084],[-100.109614,29.622824],[-100.016506,29.622824],[-99.605735,29.628301]]]}}, -{"type":"Feature","id":"48465","properties":{"name":"Val Verde"},"geometry":{"type":"Polygon","coordinates":[[[-101.544572,30.285534],[-100.958539,30.285534],[-100.701123,30.291011],[-100.701123,29.622824],[-100.794231,29.239438],[-101.413125,29.754271],[-101.76365,29.781655],[-101.758173,30.285534],[-101.544572,30.285534]]]}}, -{"type":"Feature","id":"48467","properties":{"name":"Van Zandt"},"geometry":{"type":"Polygon","coordinates":[[[-96.062155,32.837788],[-95.936185,32.837788],[-95.634953,32.722772],[-95.596615,32.684434],[-95.448737,32.355817],[-96.078585,32.355817],[-96.078585,32.837788],[-96.062155,32.837788]]]}}, -{"type":"Feature","id":"48469","properties":{"name":"Victoria"},"geometry":{"type":"Polygon","coordinates":[[[-96.976804,29.102515],[-96.938465,29.064176],[-96.64271,28.713652],[-96.653664,28.702698],[-96.889173,28.505528],[-97.146589,28.549344],[-97.16302,28.554821],[-97.30542,28.861529],[-96.976804,29.102515]]]}}, -{"type":"Feature","id":"48471","properties":{"name":"Walker"},"geometry":{"type":"Polygon","coordinates":[[[-95.432306,31.057782],[-95.328245,30.860613],[-95.361106,30.504611],[-95.832123,30.630581],[-95.864985,30.86609],[-95.618522,30.931813],[-95.432306,31.057782]]]}}, -{"type":"Feature","id":"48473","properties":{"name":"Waller"},"geometry":{"type":"Polygon","coordinates":[[[-95.821169,30.247195],[-95.804738,30.247195],[-95.804738,30.088364],[-95.826646,29.787132],[-95.826646,29.787132],[-96.03477,29.726886],[-96.144309,30.071933],[-96.095016,30.225288],[-95.821169,30.247195]]]}}, -{"type":"Feature","id":"48475","properties":{"name":"Ward"},"geometry":{"type":"Polygon","coordinates":[[[-102.798791,31.649292],[-102.76593,31.649292],[-102.76593,31.293291],[-102.83713,31.282337],[-103.012392,31.369968],[-103.609378,31.649292],[-103.330055,31.649292],[-102.798791,31.649292]]]}}, -{"type":"Feature","id":"48477","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-96.297663,30.378642],[-96.155263,30.329349],[-96.095016,30.225288],[-96.144309,30.071933],[-96.379817,30.082887],[-96.620803,30.044549],[-96.796065,30.159564],[-96.64271,30.296488],[-96.297663,30.378642]]]}}, -{"type":"Feature","id":"48479","properties":{"name":"Webb"},"geometry":{"type":"Polygon","coordinates":[[[-100.115091,28.19882],[-99.392134,28.204297],[-98.800625,28.056419],[-98.800625,27.355371],[-98.953979,27.26774],[-99.359273,27.306078],[-99.452381,27.262263],[-100.213675,28.19882],[-100.115091,28.19882]]]}}, -{"type":"Feature","id":"48481","properties":{"name":"Wharton"},"geometry":{"type":"Polygon","coordinates":[[[-96.17717,29.633778],[-96.089539,29.600916],[-95.848554,29.261346],[-95.875939,29.228484],[-96.308617,28.965591],[-96.64271,29.250392],[-96.17717,29.633778]]]}}, -{"type":"Feature","id":"48483","properties":{"name":"Wheeler"},"geometry":{"type":"Polygon","coordinates":[[[-100.542292,35.620074],[-100.000075,35.620074],[-100.000075,35.422904],[-100.000075,35.181919],[-100.093183,35.181919],[-100.536815,35.181919],[-100.542292,35.620074]]]}}, -{"type":"Feature","id":"48485","properties":{"name":"Wichita"},"geometry":{"type":"Polygon","coordinates":[[[-98.608932,34.157731],[-98.422716,34.081054],[-98.422716,33.834591],[-98.43367,33.834591],[-98.953979,33.834591],[-98.953979,34.2125],[-98.608932,34.157731]]]}}, -{"type":"Feature","id":"48487","properties":{"name":"Wilbarger"},"geometry":{"type":"Polygon","coordinates":[[[-99.211395,34.33847],[-98.953979,34.2125],[-98.953979,33.834591],[-98.992318,33.834591],[-99.474288,33.834591],[-99.474288,34.08653],[-99.474288,34.398716],[-99.211395,34.33847]]]}}, -{"type":"Feature","id":"48489","properties":{"name":"Willacy"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-97.655944,26.599553],[-97.442344,26.599553],[-97.382097,26.413337],[-97.864068,26.347614],[-97.957176,26.610507],[-97.655944,26.599553]]],[[[-97.316374,26.599553],[-97.288989,26.599553],[-97.223266,26.413337],[-97.239697,26.413337],[-97.316374,26.599553]]]]}}, -{"type":"Feature","id":"48491","properties":{"name":"Williamson"},"geometry":{"type":"Polygon","coordinates":[[[-97.831206,30.904428],[-97.316374,30.751074],[-97.157543,30.455319],[-97.332805,30.40055],[-97.371143,30.41698],[-97.973607,30.625104],[-98.050284,30.625104],[-97.831206,30.904428]]]}}, -{"type":"Feature","id":"48493","properties":{"name":"Wilson"},"geometry":{"type":"Polygon","coordinates":[[[-98.285792,29.255869],[-98.132438,29.442085],[-97.84216,29.376362],[-97.727145,29.223007],[-98.192684,28.883437],[-98.406285,29.113469],[-98.285792,29.255869]]]}}, -{"type":"Feature","id":"48495","properties":{"name":"Winkler"},"geometry":{"type":"Polygon","coordinates":[[[-103.061684,32.087447],[-102.798791,32.087447],[-102.798791,31.649292],[-103.330055,31.649292],[-103.324578,31.999816],[-103.061684,32.087447]]]}}, -{"type":"Feature","id":"48497","properties":{"name":"Wise"},"geometry":{"type":"Polygon","coordinates":[[[-97.50259,33.434775],[-97.486159,33.434775],[-97.382097,33.429298],[-97.398528,32.991142],[-97.535452,32.996619],[-97.546405,32.996619],[-97.924314,33.002096],[-97.918837,33.434775],[-97.50259,33.434775]]]}}, -{"type":"Feature","id":"48499","properties":{"name":"Wood"},"geometry":{"type":"Polygon","coordinates":[[[-95.152983,33.01305],[-95.152983,32.903511],[-95.152983,32.569418],[-95.574707,32.67348],[-95.596615,32.684434],[-95.634953,32.722772],[-95.667815,32.958281],[-95.306337,32.963758],[-95.152983,33.01305]]]}}, -{"type":"Feature","id":"48501","properties":{"name":"Yoakum"},"geometry":{"type":"Polygon","coordinates":[[[-103.056207,33.390959],[-102.596144,33.390959],[-102.596144,32.958281],[-103.067161,32.958281],[-103.056207,33.390959]]]}}, -{"type":"Feature","id":"48503","properties":{"name":"Young"},"geometry":{"type":"Polygon","coordinates":[[[-98.953979,33.396436],[-98.422716,33.396436],[-98.428193,33.007573],[-98.57607,32.952804],[-98.762286,32.958281],[-98.948502,32.958281],[-98.953979,33.396436]]]}}, -{"type":"Feature","id":"48505","properties":{"name":"Zapata"},"geometry":{"type":"Polygon","coordinates":[[[-99.359273,27.306078],[-98.953979,27.26774],[-98.953979,26.785769],[-99.16758,26.572168],[-99.452381,27.262263],[-99.359273,27.306078]]]}}, -{"type":"Feature","id":"48507","properties":{"name":"Zavala"},"geometry":{"type":"Polygon","coordinates":[[[-99.414042,29.091561],[-99.408565,28.642452],[-99.780997,28.642452],[-100.115091,28.647929],[-100.109614,29.086084],[-99.414042,29.091561]]]}}, -{"type":"Feature","id":"49001","properties":{"name":"Beaver"},"geometry":{"type":"Polygon","coordinates":[[[-113.97175,38.572145],[-112.514883,38.572145],[-112.52036,38.511898],[-112.443683,38.15042],[-112.476545,38.144943],[-112.876362,38.15042],[-114.048427,38.15042],[-114.048427,38.572145],[-113.97175,38.572145]]]}}, -{"type":"Feature","id":"49003","properties":{"name":"Box Elder"},"geometry":{"type":"Polygon","coordinates":[[[-112.164359,41.995232],[-111.885035,41.425631],[-112.492976,41.075106],[-113.073531,40.998429],[-114.04295,40.998429],[-114.04295,41.995232],[-113.002331,42.000709],[-112.164359,41.995232]]]}}, -{"type":"Feature","id":"49005","properties":{"name":"Cache"},"geometry":{"type":"Polygon","coordinates":[[[-111.507126,42.000709],[-111.512603,41.425631],[-111.655004,41.4092],[-111.885035,41.425631],[-112.164359,41.995232],[-112.10959,41.995232],[-111.507126,42.000709]]]}}, -{"type":"Feature","id":"49007","properties":{"name":"Carbon"},"geometry":{"type":"Polygon","coordinates":[[[-111.014202,39.81541],[-110.855371,39.81541],[-109.968106,39.804456],[-110.022876,39.470363],[-111.079925,39.464886],[-111.24971,39.705871],[-111.24971,39.81541],[-111.014202,39.81541]]]}}, -{"type":"Feature","id":"49009","properties":{"name":"Daggett"},"geometry":{"type":"Polygon","coordinates":[[[-109.677828,40.998429],[-109.04798,40.998429],[-109.04798,40.653382],[-109.283489,40.856029],[-109.97906,40.812213],[-110.000968,40.812213],[-110.000968,40.998429],[-109.677828,40.998429]]]}}, -{"type":"Feature","id":"49011","properties":{"name":"Davis"},"geometry":{"type":"Polygon","coordinates":[[[-112.011005,41.151784],[-111.857651,41.14083],[-111.737158,40.861506],[-111.98362,40.921752],[-112.262944,40.773875],[-112.492976,41.075106],[-112.011005,41.151784]]]}}, -{"type":"Feature","id":"49013","properties":{"name":"Duchesne"},"geometry":{"type":"Polygon","coordinates":[[[-110.148845,40.812213],[-110.000968,40.812213],[-109.97906,40.812213],[-109.968106,39.804456],[-110.855371,39.81541],[-110.893709,39.897564],[-110.904663,40.680767],[-110.148845,40.812213]]]}}, -{"type":"Feature","id":"49015","properties":{"name":"Emery"},"geometry":{"type":"Polygon","coordinates":[[[-111.24971,39.705871],[-111.079925,39.464886],[-110.022876,39.470363],[-110.022876,39.459409],[-110.022876,38.500944],[-111.30448,38.511898],[-111.299003,39.032208],[-111.24971,39.705871]]]}}, -{"type":"Feature","id":"49017","properties":{"name":"Garfield"},"geometry":{"type":"Polygon","coordinates":[[[-111.84122,38.15042],[-109.929768,38.15042],[-110.647247,37.54248],[-112.684669,37.54248],[-112.476545,38.144943],[-112.443683,38.15042],[-111.84122,38.15042]]]}}, -{"type":"Feature","id":"49019","properties":{"name":"Grand"},"geometry":{"type":"Polygon","coordinates":[[[-109.053457,39.497748],[-109.053457,39.366301],[-109.058934,38.500944],[-110.022876,38.500944],[-110.022876,39.459409],[-109.053457,39.497748]]]}}, -{"type":"Feature","id":"49021","properties":{"name":"Iron"},"geometry":{"type":"Polygon","coordinates":[[[-112.876362,38.15042],[-112.476545,38.144943],[-112.684669,37.54248],[-112.903746,37.498664],[-112.898269,37.498664],[-114.053904,37.602726],[-114.048427,38.15042],[-112.876362,38.15042]]]}}, -{"type":"Feature","id":"49023","properties":{"name":"Juab"},"geometry":{"type":"Polygon","coordinates":[[[-112.18079,40.01258],[-111.64405,39.81541],[-112.016482,39.317009],[-112.23556,39.552517],[-114.048427,39.541563],[-114.048427,39.908518],[-112.339621,39.903041],[-112.18079,40.01258]]]}}, -{"type":"Feature","id":"49025","properties":{"name":"Kane"},"geometry":{"type":"Polygon","coordinates":[[[-112.903746,37.498664],[-112.684669,37.54248],[-110.647247,37.54248],[-111.414018,37.000263],[-112.542268,37.000263],[-112.898269,37.000263],[-112.898269,37.498664],[-112.903746,37.498664]]]}}, -{"type":"Feature","id":"49027","properties":{"name":"Millard"},"geometry":{"type":"Polygon","coordinates":[[[-114.048427,39.541563],[-112.23556,39.552517],[-112.016482,39.317009],[-112.016482,39.043162],[-112.514883,38.572145],[-113.97175,38.572145],[-114.048427,38.572145],[-114.048427,38.676207],[-114.048427,39.541563]]]}}, -{"type":"Feature","id":"49029","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-111.419495,41.359907],[-111.266141,41.146307],[-111.638573,40.801259],[-111.737158,40.861506],[-111.857651,41.14083],[-111.419495,41.359907]]]}}, -{"type":"Feature","id":"49031","properties":{"name":"Piute"},"geometry":{"type":"Polygon","coordinates":[[[-111.857651,38.500944],[-111.764543,38.500944],[-111.84122,38.15042],[-112.443683,38.15042],[-112.52036,38.511898],[-111.857651,38.500944]]]}}, -{"type":"Feature","id":"49033","properties":{"name":"Rich"},"geometry":{"type":"Polygon","coordinates":[[[-111.047063,42.000709],[-111.047063,41.578985],[-111.047063,41.250368],[-111.266141,41.146307],[-111.419495,41.359907],[-111.512603,41.425631],[-111.507126,42.000709],[-111.047063,42.000709]]]}}, -{"type":"Feature","id":"49035","properties":{"name":"Salt Lake"},"geometry":{"type":"Polygon","coordinates":[[[-111.98362,40.921752],[-111.737158,40.861506],[-111.638573,40.801259],[-111.550942,40.609566],[-111.594758,40.576705],[-111.594758,40.576705],[-112.175313,40.467166],[-112.262944,40.773875],[-111.98362,40.921752]]]}}, -{"type":"Feature","id":"49037","properties":{"name":"San Juan"},"geometry":{"type":"Polygon","coordinates":[[[-110.022876,38.500944],[-109.058934,38.500944],[-109.042503,38.15042],[-109.042503,37.88205],[-109.042503,37.482234],[-109.042503,37.000263],[-110.000968,37.000263],[-110.751309,37.00574],[-111.414018,37.000263],[-110.647247,37.54248],[-109.929768,38.15042],[-110.022876,38.500944]]]}}, -{"type":"Feature","id":"49039","properties":{"name":"Sanpete"},"geometry":{"type":"Polygon","coordinates":[[[-111.556419,39.81541],[-111.24971,39.81541],[-111.24971,39.705871],[-111.299003,39.032208],[-111.978143,39.043162],[-112.016482,39.043162],[-112.016482,39.317009],[-111.64405,39.81541],[-111.556419,39.81541]]]}}, -{"type":"Feature","id":"49041","properties":{"name":"Sevier"},"geometry":{"type":"Polygon","coordinates":[[[-111.978143,39.043162],[-111.299003,39.032208],[-111.30448,38.511898],[-111.764543,38.500944],[-111.857651,38.500944],[-112.52036,38.511898],[-112.514883,38.572145],[-112.016482,39.043162],[-111.978143,39.043162]]]}}, -{"type":"Feature","id":"49043","properties":{"name":"Summit"},"geometry":{"type":"Polygon","coordinates":[[[-111.047063,41.250368],[-111.047063,40.998429],[-110.05026,40.998429],[-110.000968,40.998429],[-110.000968,40.812213],[-110.148845,40.812213],[-110.904663,40.680767],[-111.430449,40.686244],[-111.550942,40.609566],[-111.638573,40.801259],[-111.266141,41.146307],[-111.047063,41.250368]]]}}, -{"type":"Feature","id":"49045","properties":{"name":"Tooele"},"geometry":{"type":"Polygon","coordinates":[[[-113.073531,40.998429],[-112.492976,41.075106],[-112.262944,40.773875],[-112.175313,40.467166],[-112.18079,40.01258],[-112.339621,39.903041],[-114.048427,39.908518],[-114.048427,40.116642],[-114.04295,40.998429],[-113.073531,40.998429]]]}}, -{"type":"Feature","id":"49047","properties":{"name":"Uintah"},"geometry":{"type":"Polygon","coordinates":[[[-109.283489,40.856029],[-109.04798,40.653382],[-109.053457,40.220704],[-109.053457,39.662056],[-109.053457,39.497748],[-110.022876,39.459409],[-110.022876,39.470363],[-109.968106,39.804456],[-109.97906,40.812213],[-109.283489,40.856029]]]}}, -{"type":"Feature","id":"49049","properties":{"name":"Utah"},"geometry":{"type":"Polygon","coordinates":[[[-111.594758,40.576705],[-111.594758,40.576705],[-110.893709,39.897564],[-110.855371,39.81541],[-111.014202,39.81541],[-111.24971,39.81541],[-111.556419,39.81541],[-111.64405,39.81541],[-112.18079,40.01258],[-112.175313,40.467166],[-111.594758,40.576705]]]}}, -{"type":"Feature","id":"49051","properties":{"name":"Wasatch"},"geometry":{"type":"Polygon","coordinates":[[[-111.430449,40.686244],[-110.904663,40.680767],[-110.893709,39.897564],[-111.594758,40.576705],[-111.550942,40.609566],[-111.430449,40.686244]]]}}, -{"type":"Feature","id":"49053","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-114.053904,37.602726],[-112.898269,37.498664],[-112.898269,37.000263],[-114.048427,37.000263],[-114.053904,37.602726]]]}}, -{"type":"Feature","id":"49055","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-111.764543,38.500944],[-111.30448,38.511898],[-110.022876,38.500944],[-109.929768,38.15042],[-111.84122,38.15042],[-111.764543,38.500944]]]}}, -{"type":"Feature","id":"49057","properties":{"name":"Weber"},"geometry":{"type":"Polygon","coordinates":[[[-111.655004,41.4092],[-111.512603,41.425631],[-111.419495,41.359907],[-111.857651,41.14083],[-112.011005,41.151784],[-112.492976,41.075106],[-111.885035,41.425631],[-111.655004,41.4092]]]}}, -{"type":"Feature","id":"50001","properties":{"name":"Addison"},"geometry":{"type":"Polygon","coordinates":[[[-73.22879,44.262686],[-72.954943,44.164101],[-72.741343,44.027177],[-72.790635,43.961454],[-72.96042,43.82453],[-73.365714,43.75333],[-73.376668,43.8081],[-73.310944,44.262686],[-73.22879,44.262686]]]}}, -{"type":"Feature","id":"50003","properties":{"name":"Bennington"},"geometry":{"type":"Polygon","coordinates":[[[-73.256175,43.315175],[-72.867312,43.298744],[-72.81802,43.254929],[-72.927559,42.740096],[-73.020667,42.740096],[-73.267129,42.745573],[-73.272606,42.942743],[-73.256175,43.315175]]]}}, -{"type":"Feature","id":"50005","properties":{"name":"Caledonia"},"geometry":{"type":"Polygon","coordinates":[[[-71.941709,44.766564],[-71.837647,44.350317],[-72.040294,44.153147],[-72.368911,44.202439],[-72.42368,44.503671],[-72.434634,44.503671],[-72.374388,44.585825],[-71.941709,44.766564]]]}}, -{"type":"Feature","id":"50007","properties":{"name":"Chittenden"},"geometry":{"type":"Polygon","coordinates":[[[-73.22879,44.722749],[-72.922082,44.635118],[-72.807066,44.454379],[-72.954943,44.164101],[-73.22879,44.262686],[-73.310944,44.262686],[-73.338329,44.547487],[-73.360237,44.563917],[-73.22879,44.722749]]]}}, -{"type":"Feature","id":"50009","properties":{"name":"Essex"},"geometry":{"type":"Polygon","coordinates":[[[-71.503554,45.013027],[-71.766447,44.405086],[-71.837647,44.350317],[-71.941709,44.766564],[-71.897894,45.00755],[-71.503554,45.013027]]]}}, -{"type":"Feature","id":"50011","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-72.555127,45.00755],[-72.577034,44.782995],[-72.675619,44.793949],[-72.922082,44.635118],[-73.22879,44.722749],[-73.190452,45.013027],[-72.555127,45.00755]]]}}, -{"type":"Feature","id":"50013","properties":{"name":"Grand Isle"},"geometry":{"type":"Polygon","coordinates":[[[-73.190452,45.013027],[-73.22879,44.722749],[-73.360237,44.563917],[-73.343806,45.013027],[-73.190452,45.013027]]]}}, -{"type":"Feature","id":"50015","properties":{"name":"Lamoille"},"geometry":{"type":"Polygon","coordinates":[[[-72.675619,44.793949],[-72.577034,44.782995],[-72.374388,44.585825],[-72.434634,44.503671],[-72.807066,44.454379],[-72.922082,44.635118],[-72.675619,44.793949]]]}}, -{"type":"Feature","id":"50017","properties":{"name":"Orange"},"geometry":{"type":"Polygon","coordinates":[[[-72.434634,44.153147],[-72.368911,44.202439],[-72.040294,44.153147],[-72.204602,43.769761],[-72.790635,43.961454],[-72.741343,44.027177],[-72.434634,44.153147]]]}}, -{"type":"Feature","id":"50019","properties":{"name":"Orleans"},"geometry":{"type":"Polygon","coordinates":[[[-71.897894,45.00755],[-71.941709,44.766564],[-72.374388,44.585825],[-72.577034,44.782995],[-72.555127,45.00755],[-71.897894,45.00755]]]}}, -{"type":"Feature","id":"50021","properties":{"name":"Rutland"},"geometry":{"type":"Polygon","coordinates":[[[-73.365714,43.75333],[-72.96042,43.82453],[-72.867312,43.298744],[-73.256175,43.315175],[-73.365714,43.75333]]]}}, -{"type":"Feature","id":"50023","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-72.42368,44.503671],[-72.368911,44.202439],[-72.434634,44.153147],[-72.741343,44.027177],[-72.954943,44.164101],[-72.807066,44.454379],[-72.434634,44.503671],[-72.42368,44.503671]]]}}, -{"type":"Feature","id":"50025","properties":{"name":"Windham"},"geometry":{"type":"Polygon","coordinates":[[[-72.81802,43.254929],[-72.434634,43.233021],[-72.451065,43.161821],[-72.456542,42.729142],[-72.927559,42.740096],[-72.81802,43.254929]]]}}, -{"type":"Feature","id":"50027","properties":{"name":"Windsor"},"geometry":{"type":"Polygon","coordinates":[[[-72.790635,43.961454],[-72.204602,43.769761],[-72.330572,43.599976],[-72.434634,43.233021],[-72.81802,43.254929],[-72.867312,43.298744],[-72.96042,43.82453],[-72.790635,43.961454]]]}}, -{"type":"Feature","id":"51001","properties":{"name":"Accomack"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-75.397659,38.013497],[-75.244304,38.029928],[-75.666029,37.465803],[-75.939876,37.547957],[-75.671506,37.95325],[-75.622213,37.991589],[-75.397659,38.013497]]],[[[-76.016553,37.95325],[-75.994645,37.95325],[-76.043938,37.95325],[-76.016553,37.95325]]]]}}, -{"type":"Feature","id":"51003","properties":{"name":"Albemarle"},"geometry":{"type":"Polygon","coordinates":[[[-78.371637,38.183282],[-78.207329,38.133989],[-78.305914,38.00802],[-78.49213,37.794419],[-78.645484,37.734173],[-78.837177,38.046358],[-78.749546,38.20519],[-78.661915,38.27639],[-78.371637,38.183282]]]}}, -{"type":"Feature","id":"51005","properties":{"name":"Alleghany"},"geometry":{"type":"Polygon","coordinates":[[[-79.998289,37.958727],[-79.653241,37.871096],[-79.675149,37.761557],[-79.790165,37.794419],[-80.020196,37.646542],[-80.222843,37.630111],[-80.294043,37.690357],[-80.058535,37.95325],[-79.998289,37.958727]]]}}, -{"type":"Feature","id":"51007","properties":{"name":"Amelia"},"geometry":{"type":"Polygon","coordinates":[[[-77.988251,37.48771],[-77.856805,37.41651],[-77.648681,37.263156],[-77.796559,37.191956],[-78.229237,37.296018],[-78.234714,37.367218],[-78.130652,37.454849],[-77.988251,37.48771]]]}}, -{"type":"Feature","id":"51009","properties":{"name":"Amherst"},"geometry":{"type":"Polygon","coordinates":[[[-79.439641,37.619157],[-79.171271,37.805373],[-78.870039,37.54248],[-79.017916,37.427464],[-79.083639,37.394602],[-79.187701,37.465803],[-79.439641,37.619157]]]}}, -{"type":"Feature","id":"51011","properties":{"name":"Appomattox"},"geometry":{"type":"Polygon","coordinates":[[[-78.826223,37.553434],[-78.596192,37.400079],[-78.683823,37.246725],[-78.6893,37.246725],[-78.826223,37.20291],[-79.001485,37.400079],[-79.017916,37.427464],[-78.870039,37.54248],[-78.826223,37.553434]]]}}, -{"type":"Feature","id":"51013","properties":{"name":"Arlington"},"geometry":{"type":"Polygon","coordinates":[[[-77.117418,38.933623],[-77.046218,38.840515],[-77.084556,38.845992],[-77.111941,38.845992],[-77.15028,38.878853],[-77.172187,38.895284],[-77.117418,38.933623]]]}}, -{"type":"Feature","id":"51015","properties":{"name":"Augusta"},"geometry":{"type":"Polygon","coordinates":[[[-79.313671,38.413313],[-79.22604,38.479037],[-78.749546,38.20519],[-78.837177,38.046358],[-78.859085,38.029928],[-79.15484,37.893004],[-79.483456,38.084697],[-79.510841,38.177805],[-79.313671,38.413313]]]}}, -{"type":"Feature","id":"51017","properties":{"name":"Bath"},"geometry":{"type":"Polygon","coordinates":[[[-79.795642,38.265436],[-79.510841,38.177805],[-79.483456,38.084697],[-79.653241,37.871096],[-79.998289,37.958727],[-80.058535,37.95325],[-79.95995,38.062789],[-79.795642,38.265436]]]}}, -{"type":"Feature","id":"51019","properties":{"name":"Bedford"},"geometry":{"type":"Polygon","coordinates":[[[-79.439641,37.619157],[-79.187701,37.465803],[-79.187701,37.465803],[-79.258902,37.356264],[-79.445118,37.055032],[-79.592995,37.044078],[-79.784688,37.230294],[-79.844934,37.224817],[-79.844934,37.306971],[-79.499887,37.531526],[-79.439641,37.619157]]]}}, -{"type":"Feature","id":"51021","properties":{"name":"Bland"},"geometry":{"type":"Polygon","coordinates":[[[-81.225123,37.235771],[-80.978661,37.290541],[-80.852691,37.14814],[-80.912938,37.071463],[-81.378478,36.95097],[-81.438724,37.011217],[-81.225123,37.235771]]]}}, -{"type":"Feature","id":"51023","properties":{"name":"Botetourt"},"geometry":{"type":"Polygon","coordinates":[[[-79.790165,37.794419],[-79.675149,37.761557],[-79.499887,37.531526],[-79.844934,37.306971],[-80.074966,37.421987],[-80.020196,37.646542],[-79.790165,37.794419]]]}}, -{"type":"Feature","id":"51025","properties":{"name":"Brunswick"},"geometry":{"type":"Polygon","coordinates":[[[-78.004682,37.022171],[-77.889666,36.989309],[-77.659635,36.896201],[-77.769174,36.545677],[-77.90062,36.545677],[-78.048498,36.545677],[-78.02659,36.775708],[-78.004682,37.022171]]]}}, -{"type":"Feature","id":"51027","properties":{"name":"Buchanan"},"geometry":{"type":"Polygon","coordinates":[[[-81.969987,37.537003],[-81.926172,37.509618],[-81.739956,37.241248],[-81.898787,37.142663],[-82.150726,37.044078],[-82.315034,37.296018],[-82.315034,37.296018],[-81.969987,37.537003]]]}}, -{"type":"Feature","id":"51029","properties":{"name":"Buckingham"},"geometry":{"type":"Polygon","coordinates":[[[-78.49213,37.794419],[-78.240191,37.690357],[-78.464745,37.339833],[-78.596192,37.400079],[-78.826223,37.553434],[-78.645484,37.734173],[-78.49213,37.794419]]]}}, -{"type":"Feature","id":"51031","properties":{"name":"Campbell"},"geometry":{"type":"Polygon","coordinates":[[[-79.001485,37.400079],[-78.826223,37.20291],[-78.9029,37.022171],[-78.974101,37.049555],[-79.094593,37.060509],[-79.302717,37.109802],[-79.445118,37.055032],[-79.258902,37.356264],[-79.083639,37.394602],[-79.017916,37.427464],[-79.001485,37.400079]]]}}, -{"type":"Feature","id":"51033","properties":{"name":"Caroline"},"geometry":{"type":"Polygon","coordinates":[[[-77.325542,38.243528],[-77.117418,38.15042],[-77.068125,37.964204],[-77.073602,37.964204],[-77.183141,37.893004],[-77.347449,37.788942],[-77.643204,37.991589],[-77.369357,38.249005],[-77.325542,38.243528]]]}}, -{"type":"Feature","id":"51035","properties":{"name":"Carroll"},"geometry":{"type":"Polygon","coordinates":[[[-80.633614,36.929063],[-80.463828,36.709985],[-80.611706,36.556631],[-80.83626,36.556631],[-80.83626,36.556631],[-80.912938,36.649739],[-80.934845,36.671646],[-81.044384,36.80857],[-80.743152,36.87977],[-80.633614,36.929063]]]}}, -{"type":"Feature","id":"51036","properties":{"name":"Charles City"},"geometry":{"type":"Polygon","coordinates":[[[-77.040741,37.427464],[-76.903817,37.378172],[-76.881909,37.224817],[-76.975017,37.246725],[-77.270772,37.323402],[-77.248864,37.383649],[-77.177664,37.493187],[-77.040741,37.427464]]]}}, -{"type":"Feature","id":"51037","properties":{"name":"Charlotte"},"geometry":{"type":"Polygon","coordinates":[[[-78.6893,37.246725],[-78.683823,37.246725],[-78.442837,37.07694],[-78.49213,36.890724],[-78.650961,36.699031],[-78.9029,37.022171],[-78.826223,37.20291],[-78.6893,37.246725]]]}}, -{"type":"Feature","id":"51041","properties":{"name":"Chesterfield"},"geometry":{"type":"Polygon","coordinates":[[[-77.654158,37.564388],[-77.593912,37.553434],[-77.41865,37.449372],[-77.248864,37.383649],[-77.270772,37.323402],[-77.281726,37.312448],[-77.298157,37.312448],[-77.298157,37.312448],[-77.336496,37.312448],[-77.374834,37.246725],[-77.402219,37.241248],[-77.402219,37.235771],[-77.41865,37.235771],[-77.446034,37.224817],[-77.648681,37.263156],[-77.856805,37.41651],[-77.654158,37.564388]]]}}, -{"type":"Feature","id":"51043","properties":{"name":"Clarke"},"geometry":{"type":"Polygon","coordinates":[[[-78.032067,39.262239],[-78.032067,39.262239],[-77.82942,39.130793],[-77.960867,39.015777],[-78.004682,38.977438],[-78.15256,39.037685],[-78.032067,39.262239]]]}}, -{"type":"Feature","id":"51045","properties":{"name":"Craig"},"geometry":{"type":"Polygon","coordinates":[[[-80.020196,37.646542],[-80.074966,37.421987],[-80.173551,37.378172],[-80.261182,37.339833],[-80.430967,37.312448],[-80.474782,37.421987],[-80.222843,37.630111],[-80.020196,37.646542]]]}}, -{"type":"Feature","id":"51047","properties":{"name":"Culpeper"},"geometry":{"type":"Polygon","coordinates":[[[-77.933482,38.698114],[-77.637727,38.407836],[-77.621296,38.369498],[-77.703451,38.358544],[-77.895143,38.391406],[-78.092313,38.309252],[-78.229237,38.533806],[-77.933482,38.698114]]]}}, -{"type":"Feature","id":"51049","properties":{"name":"Cumberland"},"geometry":{"type":"Polygon","coordinates":[[[-78.163514,37.750604],[-78.158037,37.750604],[-78.070406,37.657496],[-78.130652,37.454849],[-78.234714,37.367218],[-78.262098,37.34531],[-78.464745,37.339833],[-78.240191,37.690357],[-78.163514,37.750604]]]}}, -{"type":"Feature","id":"51051","properties":{"name":"Dickenson"},"geometry":{"type":"Polygon","coordinates":[[[-82.315034,37.296018],[-82.150726,37.044078],[-82.325988,36.972878],[-82.55602,37.20291],[-82.315034,37.296018],[-82.315034,37.296018]]]}}, -{"type":"Feature","id":"51053","properties":{"name":"Dinwiddie"},"geometry":{"type":"Polygon","coordinates":[[[-77.648681,37.263156],[-77.446034,37.224817],[-77.396742,37.170048],[-77.396742,36.994786],[-77.621296,36.87977],[-77.659635,36.896201],[-77.889666,36.989309],[-77.796559,37.191956],[-77.648681,37.263156]]]}}, -{"type":"Feature","id":"51057","properties":{"name":"Essex"},"geometry":{"type":"Polygon","coordinates":[[[-77.062649,38.161374],[-76.936679,38.07922],[-76.777848,37.876573],[-76.68474,37.772511],[-76.750463,37.728696],[-77.068125,37.964204],[-77.117418,38.15042],[-77.062649,38.161374]]]}}, -{"type":"Feature","id":"51059","properties":{"name":"Fairfax"},"geometry":{"type":"Polygon","coordinates":[[[-77.331019,39.059592],[-77.117418,38.933623],[-77.172187,38.895284],[-77.15028,38.878853],[-77.111941,38.845992],[-77.040741,38.785745],[-77.084556,38.709068],[-77.128372,38.632391],[-77.22148,38.637868],[-77.533665,38.845992],[-77.331019,39.059592]]]}}, -{"type":"Feature","id":"51061","properties":{"name":"Fauquier"},"geometry":{"type":"Polygon","coordinates":[[[-77.960867,39.015777],[-77.654158,38.944577],[-77.533665,38.555714],[-77.637727,38.407836],[-77.933482,38.698114],[-78.130652,38.862422],[-78.004682,38.977438],[-77.960867,39.015777]]]}}, -{"type":"Feature","id":"51063","properties":{"name":"Floyd"},"geometry":{"type":"Polygon","coordinates":[[[-80.129735,37.120755],[-80.233797,36.874293],[-80.463828,36.709985],[-80.633614,36.929063],[-80.545983,36.983832],[-80.179028,37.115279],[-80.129735,37.120755]]]}}, -{"type":"Feature","id":"51065","properties":{"name":"Fluvanna"},"geometry":{"type":"Polygon","coordinates":[[[-78.305914,38.00802],[-78.064929,37.903958],[-78.158037,37.750604],[-78.163514,37.750604],[-78.240191,37.690357],[-78.49213,37.794419],[-78.305914,38.00802]]]}}, -{"type":"Feature","id":"51067","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-79.784688,37.230294],[-79.592995,37.044078],[-79.642287,36.857862],[-79.647764,36.852385],[-80.042104,36.792139],[-80.233797,36.874293],[-80.129735,37.120755],[-79.844934,37.224817],[-79.784688,37.230294]]]}}, -{"type":"Feature","id":"51069","properties":{"name":"Frederick"},"geometry":{"type":"Polygon","coordinates":[[[-78.349729,39.464886],[-78.229237,39.393686],[-78.032067,39.262239],[-78.032067,39.262239],[-78.15256,39.037685],[-78.311391,39.0103],[-78.338776,39.103408],[-78.541422,39.054115],[-78.508561,39.086977],[-78.349729,39.464886]]]}}, -{"type":"Feature","id":"51071","properties":{"name":"Giles"},"geometry":{"type":"Polygon","coordinates":[[[-80.474782,37.421987],[-80.430967,37.312448],[-80.606229,37.246725],[-80.852691,37.14814],[-80.978661,37.290541],[-80.858168,37.427464],[-80.858168,37.427464],[-80.474782,37.421987]]]}}, -{"type":"Feature","id":"51073","properties":{"name":"Gloucester"},"geometry":{"type":"Polygon","coordinates":[[[-76.62997,37.591772],[-76.438277,37.515095],[-76.405416,37.400079],[-76.498524,37.241248],[-76.657355,37.378172],[-76.712124,37.432941],[-76.651878,37.602726],[-76.62997,37.591772]]]}}, -{"type":"Feature","id":"51075","properties":{"name":"Goochland"},"geometry":{"type":"Polygon","coordinates":[[[-78.064929,37.903958],[-77.796559,37.728696],[-77.63225,37.706788],[-77.654158,37.564388],[-78.015636,37.641065],[-78.070406,37.657496],[-78.158037,37.750604],[-78.064929,37.903958]]]}}, -{"type":"Feature","id":"51077","properties":{"name":"Grayson"},"geometry":{"type":"Polygon","coordinates":[[[-81.044384,36.80857],[-80.934845,36.671646],[-80.912938,36.649739],[-80.83626,36.556631],[-80.901984,36.562108],[-80.978661,36.562108],[-81.351093,36.573061],[-81.679709,36.589492],[-81.646848,36.6114],[-81.608509,36.638785],[-81.263462,36.764754],[-81.044384,36.80857]]]}}, -{"type":"Feature","id":"51079","properties":{"name":"Greene"},"geometry":{"type":"Polygon","coordinates":[[[-78.459268,38.468083],[-78.453791,38.47356],[-78.289483,38.270913],[-78.371637,38.183282],[-78.661915,38.27639],[-78.486653,38.41879],[-78.459268,38.468083]]]}}, -{"type":"Feature","id":"51081","properties":{"name":"Greensville"},"geometry":{"type":"Polygon","coordinates":[[[-77.621296,36.87977],[-77.429604,36.709985],[-77.298157,36.545677],[-77.769174,36.545677],[-77.659635,36.896201],[-77.621296,36.87977]]]}}, -{"type":"Feature","id":"51083","properties":{"name":"Halifax"},"geometry":{"type":"Polygon","coordinates":[[[-78.974101,37.049555],[-78.9029,37.022171],[-78.650961,36.699031],[-78.733115,36.5402],[-78.798839,36.5402],[-79.138409,36.5402],[-79.220563,36.5402],[-79.094593,37.060509],[-78.974101,37.049555]]]}}, -{"type":"Feature","id":"51085","properties":{"name":"Hanover"},"geometry":{"type":"Polygon","coordinates":[[[-77.68702,38.00802],[-77.643204,37.991589],[-77.347449,37.788942],[-77.122895,37.624634],[-77.226957,37.537003],[-77.63225,37.706788],[-77.796559,37.728696],[-77.68702,38.00802]]]}}, -{"type":"Feature","id":"51087","properties":{"name":"Henrico"},"geometry":{"type":"Polygon","coordinates":[[[-77.63225,37.706788],[-77.226957,37.537003],[-77.177664,37.493187],[-77.248864,37.383649],[-77.41865,37.449372],[-77.473419,37.597249],[-77.593912,37.553434],[-77.654158,37.564388],[-77.63225,37.706788]]]}}, -{"type":"Feature","id":"51089","properties":{"name":"Henry"},"geometry":{"type":"Polygon","coordinates":[[[-79.647764,36.852385],[-79.642287,36.857862],[-79.713488,36.5402],[-79.965427,36.5402],[-80.025673,36.5402],[-80.053058,36.5402],[-80.042104,36.792139],[-79.647764,36.852385]]]}}, -{"type":"Feature","id":"51091","properties":{"name":"Highland"},"geometry":{"type":"Polygon","coordinates":[[[-79.647764,38.594052],[-79.313671,38.413313],[-79.510841,38.177805],[-79.795642,38.265436],[-79.647764,38.594052]]]}}, -{"type":"Feature","id":"51093","properties":{"name":"Isle of Wight"},"geometry":{"type":"Polygon","coordinates":[[[-76.482093,36.929063],[-76.89834,36.644262],[-76.909294,36.649739],[-76.925725,36.709985],[-76.860002,36.961924],[-76.849048,36.994786],[-76.673786,37.142663],[-76.482093,36.929063]]]}}, -{"type":"Feature","id":"51095","properties":{"name":"James City"},"geometry":{"type":"Polygon","coordinates":[[[-76.739509,37.465803],[-76.712124,37.432941],[-76.657355,37.378172],[-76.728555,37.306971],[-76.679263,37.268633],[-76.591632,37.213863],[-76.613539,37.164571],[-76.794278,37.208387],[-76.881909,37.224817],[-76.903817,37.378172],[-76.739509,37.465803]]]}}, -{"type":"Feature","id":"51097","properties":{"name":"King and Queen"},"geometry":{"type":"Polygon","coordinates":[[[-77.073602,37.964204],[-77.068125,37.964204],[-76.750463,37.728696],[-76.651878,37.602726],[-76.712124,37.432941],[-76.739509,37.465803],[-76.794278,37.515095],[-77.177664,37.893004],[-77.183141,37.893004],[-77.073602,37.964204]]]}}, -{"type":"Feature","id":"51099","properties":{"name":"King George"},"geometry":{"type":"Polygon","coordinates":[[[-76.996925,38.27639],[-77.062649,38.161374],[-77.117418,38.15042],[-77.325542,38.243528],[-77.287203,38.34759],[-76.996925,38.27639]]]}}, -{"type":"Feature","id":"51101","properties":{"name":"King William"},"geometry":{"type":"Polygon","coordinates":[[[-77.177664,37.893004],[-76.794278,37.515095],[-77.122895,37.624634],[-77.347449,37.788942],[-77.183141,37.893004],[-77.177664,37.893004]]]}}, -{"type":"Feature","id":"51103","properties":{"name":"Lancaster"},"geometry":{"type":"Polygon","coordinates":[[[-76.48757,37.838235],[-76.317785,37.679403],[-76.640924,37.794419],[-76.509478,37.838235],[-76.48757,37.838235]]]}}, -{"type":"Feature","id":"51105","properties":{"name":"Lee"},"geometry":{"type":"Polygon","coordinates":[[[-82.868205,36.885247],[-82.76962,36.797616],[-82.983221,36.594969],[-83.470669,36.594969],[-83.673316,36.600446],[-83.459715,36.666169],[-82.879159,36.890724],[-82.868205,36.885247]]]}}, -{"type":"Feature","id":"51107","properties":{"name":"Loudoun"},"geometry":{"type":"Polygon","coordinates":[[[-77.719881,39.322485],[-77.676066,39.322485],[-77.456988,39.218424],[-77.331019,39.059592],[-77.533665,38.845992],[-77.654158,38.944577],[-77.960867,39.015777],[-77.82942,39.130793],[-77.719881,39.322485]]]}}, -{"type":"Feature","id":"51109","properties":{"name":"Louisa"},"geometry":{"type":"Polygon","coordinates":[[[-77.95539,38.117559],[-77.68702,38.00802],[-77.796559,37.728696],[-78.064929,37.903958],[-78.305914,38.00802],[-78.207329,38.133989],[-77.95539,38.117559]]]}}, -{"type":"Feature","id":"51111","properties":{"name":"Lunenburg"},"geometry":{"type":"Polygon","coordinates":[[[-78.399022,37.087894],[-78.240191,37.120755],[-78.004682,37.022171],[-78.02659,36.775708],[-78.475699,36.885247],[-78.49213,36.890724],[-78.442837,37.07694],[-78.399022,37.087894]]]}}, -{"type":"Feature","id":"51113","properties":{"name":"Madison"},"geometry":{"type":"Polygon","coordinates":[[[-78.448314,38.500944],[-78.338776,38.626914],[-78.229237,38.533806],[-78.092313,38.309252],[-78.289483,38.270913],[-78.453791,38.47356],[-78.448314,38.500944]]]}}, -{"type":"Feature","id":"51115","properties":{"name":"Mathews"},"geometry":{"type":"Polygon","coordinates":[[[-76.356123,37.526049],[-76.356123,37.526049],[-76.405416,37.400079],[-76.438277,37.515095],[-76.356123,37.526049]]]}}, -{"type":"Feature","id":"51117","properties":{"name":"Mecklenburg"},"geometry":{"type":"Polygon","coordinates":[[[-78.475699,36.885247],[-78.02659,36.775708],[-78.048498,36.545677],[-78.322345,36.545677],[-78.459268,36.5402],[-78.470222,36.5402],[-78.733115,36.5402],[-78.650961,36.699031],[-78.49213,36.890724],[-78.475699,36.885247]]]}}, -{"type":"Feature","id":"51119","properties":{"name":"Middlesex"},"geometry":{"type":"Polygon","coordinates":[[[-76.356123,37.526049],[-76.356123,37.526049],[-76.438277,37.515095],[-76.62997,37.591772],[-76.651878,37.602726],[-76.750463,37.728696],[-76.68474,37.772511],[-76.356123,37.526049]]]}}, -{"type":"Feature","id":"51121","properties":{"name":"Montgomery"},"geometry":{"type":"Polygon","coordinates":[[[-80.261182,37.339833],[-80.179028,37.115279],[-80.545983,36.983832],[-80.578844,37.087894],[-80.529552,37.131709],[-80.606229,37.246725],[-80.430967,37.312448],[-80.261182,37.339833]]]}}, -{"type":"Feature","id":"51125","properties":{"name":"Nelson"},"geometry":{"type":"Polygon","coordinates":[[[-78.859085,38.029928],[-78.837177,38.046358],[-78.645484,37.734173],[-78.826223,37.553434],[-78.870039,37.54248],[-79.171271,37.805373],[-79.15484,37.893004],[-78.859085,38.029928]]]}}, -{"type":"Feature","id":"51127","properties":{"name":"New Kent"},"geometry":{"type":"Polygon","coordinates":[[[-77.122895,37.624634],[-76.794278,37.515095],[-76.739509,37.465803],[-76.903817,37.378172],[-77.040741,37.427464],[-77.177664,37.493187],[-77.226957,37.537003],[-77.122895,37.624634]]]}}, -{"type":"Feature","id":"51133","properties":{"name":"Northumberland"},"geometry":{"type":"Polygon","coordinates":[[[-76.317785,37.679403],[-76.48757,37.838235],[-76.509478,37.838235],[-76.635447,37.964204],[-76.520431,38.035405],[-76.317785,37.679403]]]}}, -{"type":"Feature","id":"51135","properties":{"name":"Nottoway"},"geometry":{"type":"Polygon","coordinates":[[[-78.229237,37.296018],[-77.796559,37.191956],[-77.889666,36.989309],[-78.004682,37.022171],[-78.240191,37.120755],[-78.229237,37.296018]]]}}, -{"type":"Feature","id":"51137","properties":{"name":"Orange"},"geometry":{"type":"Polygon","coordinates":[[[-77.895143,38.391406],[-77.703451,38.358544],[-77.95539,38.117559],[-78.207329,38.133989],[-78.371637,38.183282],[-78.289483,38.270913],[-78.092313,38.309252],[-77.895143,38.391406]]]}}, -{"type":"Feature","id":"51139","properties":{"name":"Page"},"geometry":{"type":"Polygon","coordinates":[[[-78.388068,38.829561],[-78.284006,38.758361],[-78.338776,38.626914],[-78.448314,38.500944],[-78.453791,38.47356],[-78.459268,38.468083],[-78.486653,38.41879],[-78.640007,38.605006],[-78.388068,38.829561]]]}}, -{"type":"Feature","id":"51141","properties":{"name":"Patrick"},"geometry":{"type":"Polygon","coordinates":[[[-80.233797,36.874293],[-80.042104,36.792139],[-80.053058,36.5402],[-80.441921,36.551154],[-80.611706,36.556631],[-80.463828,36.709985],[-80.233797,36.874293]]]}}, -{"type":"Feature","id":"51143","properties":{"name":"Pittsylvania"},"geometry":{"type":"Polygon","coordinates":[[[-79.302717,37.109802],[-79.094593,37.060509],[-79.220563,36.5402],[-79.341056,36.5402],[-79.401302,36.638785],[-79.472502,36.5402],[-79.510841,36.5402],[-79.713488,36.5402],[-79.642287,36.857862],[-79.592995,37.044078],[-79.445118,37.055032],[-79.302717,37.109802]]]}}, -{"type":"Feature","id":"51145","properties":{"name":"Powhatan"},"geometry":{"type":"Polygon","coordinates":[[[-78.015636,37.641065],[-77.654158,37.564388],[-77.856805,37.41651],[-77.988251,37.48771],[-78.130652,37.454849],[-78.070406,37.657496],[-78.015636,37.641065]]]}}, -{"type":"Feature","id":"51147","properties":{"name":"Prince Edward"},"geometry":{"type":"Polygon","coordinates":[[[-78.262098,37.34531],[-78.234714,37.367218],[-78.229237,37.296018],[-78.240191,37.120755],[-78.399022,37.087894],[-78.442837,37.07694],[-78.683823,37.246725],[-78.596192,37.400079],[-78.464745,37.339833],[-78.262098,37.34531]]]}}, -{"type":"Feature","id":"51149","properties":{"name":"Prince George"},"geometry":{"type":"Polygon","coordinates":[[[-77.281726,37.312448],[-77.270772,37.323402],[-76.975017,37.246725],[-77.155756,37.109802],[-77.396742,36.994786],[-77.396742,37.170048],[-77.374834,37.246725],[-77.336496,37.312448],[-77.281726,37.312448]]]}}, -{"type":"Feature","id":"51153","properties":{"name":"Prince William"},"geometry":{"type":"Polygon","coordinates":[[[-77.654158,38.944577],[-77.533665,38.845992],[-77.22148,38.637868],[-77.303634,38.506421],[-77.533665,38.555714],[-77.654158,38.944577]]]}}, -{"type":"Feature","id":"51155","properties":{"name":"Pulaski"},"geometry":{"type":"Polygon","coordinates":[[[-80.606229,37.246725],[-80.529552,37.131709],[-80.578844,37.087894],[-80.545983,36.983832],[-80.633614,36.929063],[-80.743152,36.87977],[-80.912938,37.071463],[-80.852691,37.14814],[-80.606229,37.246725]]]}}, -{"type":"Feature","id":"51157","properties":{"name":"Rappahannock"},"geometry":{"type":"Polygon","coordinates":[[[-78.256622,38.758361],[-78.130652,38.862422],[-77.933482,38.698114],[-78.229237,38.533806],[-78.338776,38.626914],[-78.284006,38.758361],[-78.256622,38.758361]]]}}, -{"type":"Feature","id":"51159","properties":{"name":"Richmond"},"geometry":{"type":"Polygon","coordinates":[[[-76.914771,38.095651],[-76.635447,37.964204],[-76.509478,37.838235],[-76.640924,37.794419],[-76.777848,37.876573],[-76.936679,38.07922],[-76.914771,38.095651]]]}}, -{"type":"Feature","id":"51161","properties":{"name":"Roanoke"},"geometry":{"type":"Polygon","coordinates":[[[-80.173551,37.378172],[-80.074966,37.421987],[-79.844934,37.306971],[-79.844934,37.224817],[-80.129735,37.120755],[-80.179028,37.115279],[-80.261182,37.339833],[-80.173551,37.378172]],[[-79.981858,37.328879],[-80.020196,37.306971],[-80.03115,37.263156],[-79.981858,37.328879]]]}}, -{"type":"Feature","id":"51163","properties":{"name":"Rockbridge"},"geometry":{"type":"Polygon","coordinates":[[[-79.483456,38.084697],[-79.15484,37.893004],[-79.171271,37.805373],[-79.439641,37.619157],[-79.499887,37.531526],[-79.675149,37.761557],[-79.653241,37.871096],[-79.483456,38.084697]]]}}, -{"type":"Feature","id":"51165","properties":{"name":"Rockingham"},"geometry":{"type":"Polygon","coordinates":[[[-78.990532,38.845992],[-78.870039,38.763838],[-78.640007,38.605006],[-78.486653,38.41879],[-78.661915,38.27639],[-78.749546,38.20519],[-79.22604,38.479037],[-79.056255,38.763838],[-78.990532,38.845992]]]}}, -{"type":"Feature","id":"51167","properties":{"name":"Russell"},"geometry":{"type":"Polygon","coordinates":[[[-81.898787,37.142663],[-81.778294,36.956447],[-81.838541,36.929063],[-82.331465,36.709985],[-82.408142,36.874293],[-82.325988,36.972878],[-82.150726,37.044078],[-81.898787,37.142663]]]}}, -{"type":"Feature","id":"51169","properties":{"name":"Scott"},"geometry":{"type":"Polygon","coordinates":[[[-82.479343,36.885247],[-82.408142,36.874293],[-82.331465,36.709985],[-82.293127,36.594969],[-82.610789,36.594969],[-82.654605,36.594969],[-82.829867,36.594969],[-82.983221,36.594969],[-82.76962,36.797616],[-82.479343,36.885247]]]}}, -{"type":"Feature","id":"51171","properties":{"name":"Shenandoah"},"geometry":{"type":"Polygon","coordinates":[[[-78.338776,39.103408],[-78.311391,39.0103],[-78.388068,38.829561],[-78.640007,38.605006],[-78.870039,38.763838],[-78.541422,39.054115],[-78.338776,39.103408]]]}}, -{"type":"Feature","id":"51173","properties":{"name":"Smyth"},"geometry":{"type":"Polygon","coordinates":[[[-81.477062,36.989309],[-81.438724,37.011217],[-81.378478,36.95097],[-81.263462,36.764754],[-81.608509,36.638785],[-81.838541,36.929063],[-81.778294,36.956447],[-81.477062,36.989309]]]}}, -{"type":"Feature","id":"51175","properties":{"name":"Southampton"},"geometry":{"type":"Polygon","coordinates":[[[-76.860002,36.961924],[-76.925725,36.709985],[-76.909294,36.649739],[-76.89834,36.644262],[-76.914771,36.551154],[-76.914771,36.545677],[-77.16671,36.545677],[-77.298157,36.545677],[-77.429604,36.709985],[-76.95311,36.945493],[-76.849048,36.994786],[-76.860002,36.961924]]]}}, -{"type":"Feature","id":"51177","properties":{"name":"Spotsylvania"},"geometry":{"type":"Polygon","coordinates":[[[-77.621296,38.369498],[-77.528188,38.309252],[-77.446034,38.281867],[-77.369357,38.249005],[-77.643204,37.991589],[-77.68702,38.00802],[-77.95539,38.117559],[-77.703451,38.358544],[-77.621296,38.369498]]]}}, -{"type":"Feature","id":"51179","properties":{"name":"Stafford"},"geometry":{"type":"Polygon","coordinates":[[[-77.533665,38.555714],[-77.303634,38.506421],[-77.287203,38.34759],[-77.325542,38.243528],[-77.369357,38.249005],[-77.446034,38.281867],[-77.528188,38.309252],[-77.621296,38.369498],[-77.637727,38.407836],[-77.533665,38.555714]]]}}, -{"type":"Feature","id":"51181","properties":{"name":"Surry"},"geometry":{"type":"Polygon","coordinates":[[[-76.975017,37.246725],[-76.881909,37.224817],[-76.794278,37.208387],[-76.673786,37.142663],[-76.849048,36.994786],[-76.95311,36.945493],[-77.155756,37.109802],[-76.975017,37.246725]]]}}, -{"type":"Feature","id":"51183","properties":{"name":"Sussex"},"geometry":{"type":"Polygon","coordinates":[[[-77.155756,37.109802],[-76.95311,36.945493],[-77.429604,36.709985],[-77.621296,36.87977],[-77.396742,36.994786],[-77.155756,37.109802]]]}}, -{"type":"Feature","id":"51185","properties":{"name":"Tazewell"},"geometry":{"type":"Polygon","coordinates":[[[-81.373001,37.323402],[-81.362047,37.339833],[-81.225123,37.235771],[-81.438724,37.011217],[-81.477062,36.989309],[-81.778294,36.956447],[-81.898787,37.142663],[-81.739956,37.241248],[-81.373001,37.323402]]]}}, -{"type":"Feature","id":"51187","properties":{"name":"Warren"},"geometry":{"type":"Polygon","coordinates":[[[-78.15256,39.037685],[-78.004682,38.977438],[-78.130652,38.862422],[-78.256622,38.758361],[-78.284006,38.758361],[-78.388068,38.829561],[-78.311391,39.0103],[-78.15256,39.037685]]]}}, -{"type":"Feature","id":"51191","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-81.838541,36.929063],[-81.608509,36.638785],[-81.646848,36.6114],[-81.827587,36.616877],[-82.145249,36.594969],[-82.145249,36.671646],[-82.243834,36.594969],[-82.293127,36.594969],[-82.331465,36.709985],[-81.838541,36.929063]]]}}, -{"type":"Feature","id":"51193","properties":{"name":"Westmoreland"},"geometry":{"type":"Polygon","coordinates":[[[-76.520431,38.035405],[-76.635447,37.964204],[-76.914771,38.095651],[-76.936679,38.07922],[-77.062649,38.161374],[-76.996925,38.27639],[-76.520431,38.035405]]]}}, -{"type":"Feature","id":"51195","properties":{"name":"Wise"},"geometry":{"type":"Polygon","coordinates":[[[-82.55602,37.20291],[-82.325988,36.972878],[-82.408142,36.874293],[-82.479343,36.885247],[-82.76962,36.797616],[-82.868205,36.885247],[-82.879159,36.890724],[-82.868205,36.972878],[-82.566974,37.197433],[-82.55602,37.20291]]]}}, -{"type":"Feature","id":"51197","properties":{"name":"Wythe"},"geometry":{"type":"Polygon","coordinates":[[[-80.912938,37.071463],[-80.743152,36.87977],[-81.044384,36.80857],[-81.263462,36.764754],[-81.378478,36.95097],[-80.912938,37.071463]]]}}, -{"type":"Feature","id":"51199","properties":{"name":"York"},"geometry":{"type":"Polygon","coordinates":[[[-76.657355,37.378172],[-76.498524,37.241248],[-76.399939,37.164571],[-76.394462,37.104325],[-76.4328,37.093371],[-76.55877,37.213863],[-76.591632,37.213863],[-76.679263,37.268633],[-76.728555,37.306971],[-76.657355,37.378172]]]}}, -{"type":"Feature","id":"51510","properties":{"name":"Alexandria"},"geometry":{"type":"Polygon","coordinates":[[[-77.084556,38.845992],[-77.046218,38.840515],[-77.040741,38.791222],[-77.040741,38.785745],[-77.111941,38.845992],[-77.084556,38.845992]]]}}, -{"type":"Feature","id":"51520","properties":{"name":"Bristol"},"geometry":{"type":"Polygon","coordinates":[[[-82.145249,36.671646],[-82.145249,36.594969],[-82.243834,36.594969],[-82.145249,36.671646]]]}}, -{"type":"Feature","id":"51550","properties":{"name":"Chesapeake"},"geometry":{"type":"Polygon","coordinates":[[[-76.405416,36.868816],[-76.2904,36.819524],[-76.224677,36.841432],[-76.120615,36.551154],[-76.312308,36.551154],[-76.493047,36.551154],[-76.421846,36.868816],[-76.405416,36.868816]]]}}, -{"type":"Feature","id":"51590","properties":{"name":"Danville"},"geometry":{"type":"Polygon","coordinates":[[[-79.401302,36.638785],[-79.341056,36.5402],[-79.472502,36.5402],[-79.401302,36.638785]]]}}, -{"type":"Feature","id":"51650","properties":{"name":"Hampton"},"geometry":{"type":"Polygon","coordinates":[[[-76.394462,37.104325],[-76.284923,37.115279],[-76.388985,36.989309],[-76.4328,37.093371],[-76.394462,37.104325]]]}}, -{"type":"Feature","id":"51670","properties":{"name":"Hopewell"},"geometry":{"type":"Polygon","coordinates":[[[-77.298157,37.312448],[-77.281726,37.312448],[-77.336496,37.312448],[-77.298157,37.312448],[-77.298157,37.312448]]]}}, -{"type":"Feature","id":"51680","properties":{"name":"Lynchburg"},"geometry":{"type":"Polygon","coordinates":[[[-79.187701,37.465803],[-79.187701,37.465803],[-79.083639,37.394602],[-79.258902,37.356264],[-79.187701,37.465803]]]}}, -{"type":"Feature","id":"51700","properties":{"name":"Newport News"},"geometry":{"type":"Polygon","coordinates":[[[-76.55877,37.213863],[-76.4328,37.093371],[-76.388985,36.989309],[-76.613539,37.164571],[-76.591632,37.213863],[-76.55877,37.213863]]]}}, -{"type":"Feature","id":"51710","properties":{"name":"Norfolk"},"geometry":{"type":"Polygon","coordinates":[[[-76.175384,36.929063],[-76.180861,36.923586],[-76.224677,36.841432],[-76.2904,36.819524],[-76.345169,36.918109],[-76.175384,36.929063]]]}}, -{"type":"Feature","id":"51730","properties":{"name":"Petersburg"},"geometry":{"type":"Polygon","coordinates":[[[-77.402219,37.241248],[-77.374834,37.246725],[-77.396742,37.170048],[-77.446034,37.224817],[-77.41865,37.235771],[-77.402219,37.235771],[-77.402219,37.241248]]]}}, -{"type":"Feature","id":"51735","properties":{"name":"Poquoson"},"geometry":{"type":"Polygon","coordinates":[[[-76.394462,37.104325],[-76.399939,37.164571],[-76.284923,37.115279],[-76.394462,37.104325]]]}}, -{"type":"Feature","id":"51740","properties":{"name":"Portsmouth"},"geometry":{"type":"Polygon","coordinates":[[[-76.345169,36.918109],[-76.2904,36.819524],[-76.405416,36.868816],[-76.421846,36.868816],[-76.405416,36.896201],[-76.345169,36.918109]]]}}, -{"type":"Feature","id":"51760","properties":{"name":"Richmond"},"geometry":{"type":"Polygon","coordinates":[[[-77.473419,37.597249],[-77.41865,37.449372],[-77.593912,37.553434],[-77.473419,37.597249]]]}}, -{"type":"Feature","id":"51770","properties":{"name":"Roanoke"},"geometry":{"type":"Polygon","coordinates":[[[-79.981858,37.328879],[-80.03115,37.263156],[-80.020196,37.306971],[-79.981858,37.328879]]]}}, -{"type":"Feature","id":"51800","properties":{"name":"Suffolk"},"geometry":{"type":"Polygon","coordinates":[[[-76.405416,36.896201],[-76.421846,36.868816],[-76.493047,36.551154],[-76.542339,36.551154],[-76.914771,36.551154],[-76.89834,36.644262],[-76.482093,36.929063],[-76.405416,36.896201]]]}}, -{"type":"Feature","id":"51810","properties":{"name":"Virginia Beach"},"geometry":{"type":"Polygon","coordinates":[[[-76.180861,36.923586],[-76.175384,36.929063],[-75.868676,36.551154],[-75.901537,36.551154],[-76.120615,36.551154],[-76.224677,36.841432],[-76.180861,36.923586]]]}}, -{"type":"Feature","id":"53001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-118.950288,47.264049],[-117.958962,47.258572],[-118.210901,46.738263],[-119.213182,46.738263],[-119.372013,46.738263],[-118.977673,47.264049],[-118.950288,47.264049]]]}}, -{"type":"Feature","id":"53003","properties":{"name":"Asotin"},"geometry":{"type":"Polygon","coordinates":[[[-117.038836,46.426077],[-116.918344,45.993399],[-117.482468,45.998876],[-117.230529,46.464416],[-117.038836,46.426077]]]}}, -{"type":"Feature","id":"53005","properties":{"name":"Benton"},"geometry":{"type":"Polygon","coordinates":[[[-119.875891,46.628724],[-119.454167,46.678016],[-119.043396,46.190569],[-118.988627,45.998876],[-119.432259,45.916722],[-119.870414,45.834568],[-119.864937,46.042691],[-119.875891,46.628724],[-119.875891,46.628724]]]}}, -{"type":"Feature","id":"53007","properties":{"name":"Chelan"},"geometry":{"type":"Polygon","coordinates":[[[-120.702909,48.529222],[-119.870414,47.95962],[-120.319524,47.455742],[-120.094969,47.264049],[-121.11368,47.598142],[-121.119157,47.778881],[-121.004141,48.293714],[-120.702909,48.529222]]]}}, -{"type":"Feature","id":"53009","properties":{"name":"Clallam"},"geometry":{"type":"Polygon","coordinates":[[[-122.926547,48.063682],[-122.948455,47.866512],[-124.613445,47.882943],[-124.597014,48.381345],[-123.983597,48.162267],[-122.926547,48.063682]]]}}, -{"type":"Feature","id":"53011","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-122.433623,45.976968],[-122.247407,46.053645],[-122.247407,45.549767],[-122.762239,45.730506],[-122.784147,45.850998],[-122.433623,45.976968]]]}}, -{"type":"Feature","id":"53013","properties":{"name":"Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-118.227332,46.595862],[-118.216378,46.590385],[-117.849423,46.623247],[-117.602961,45.998876],[-117.975393,45.998876],[-117.997301,45.998876],[-118.227332,46.595862]]]}}, -{"type":"Feature","id":"53015","properties":{"name":"Cowlitz"},"geometry":{"type":"Polygon","coordinates":[[[-123.216825,46.387739],[-122.24193,46.387739],[-122.247407,46.053645],[-122.433623,45.976968],[-122.784147,45.850998],[-123.211348,46.174138],[-123.216825,46.387739]]]}}, -{"type":"Feature","id":"53017","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-119.021489,48.069159],[-118.98315,47.95962],[-119.213182,47.861036],[-120.007338,47.220233],[-120.094969,47.264049],[-120.319524,47.455742],[-119.870414,47.95962],[-119.021489,48.069159]]]}}, -{"type":"Feature","id":"53019","properties":{"name":"Ferry"},"geometry":{"type":"Polygon","coordinates":[[[-118.194471,49.000239],[-118.139701,48.266329],[-118.342348,47.893897],[-118.851704,47.95962],[-118.835273,49.000239],[-118.194471,49.000239]]]}}, -{"type":"Feature","id":"53021","properties":{"name":"Franklin"},"geometry":{"type":"Polygon","coordinates":[[[-119.213182,46.738263],[-118.210901,46.738263],[-118.216378,46.590385],[-118.227332,46.595862],[-118.698349,46.371308],[-119.043396,46.190569],[-119.454167,46.678016],[-119.372013,46.738263],[-119.213182,46.738263]]]}}, -{"type":"Feature","id":"53023","properties":{"name":"Garfield"},"geometry":{"type":"Polygon","coordinates":[[[-117.849423,46.623247],[-117.230529,46.464416],[-117.482468,45.998876],[-117.602961,45.998876],[-117.849423,46.623247]]]}}, -{"type":"Feature","id":"53025","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-119.213182,47.861036],[-118.98315,47.95962],[-118.972196,47.94319],[-118.977673,47.264049],[-119.372013,46.738263],[-119.454167,46.678016],[-119.875891,46.628724],[-119.875891,46.628724],[-119.974476,46.738263],[-120.007338,47.220233],[-119.213182,47.861036]]]}}, -{"type":"Feature","id":"53027","properties":{"name":"Grays Harbor"},"geometry":{"type":"Polygon","coordinates":[[[-124.323167,47.532419],[-123.507103,47.515988],[-123.200394,47.08331],[-123.162056,46.793032],[-123.183963,46.793032],[-123.370179,46.793032],[-124.098612,46.793032],[-124.356029,47.532419],[-124.323167,47.532419]]]}}, -{"type":"Feature","id":"53031","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-122.751285,47.740543],[-122.948455,47.603619],[-123.507103,47.515988],[-124.323167,47.532419],[-124.356029,47.532419],[-124.613445,47.882943],[-122.948455,47.866512],[-122.926547,48.063682],[-122.751285,47.740543]]]}}, -{"type":"Feature","id":"53033","properties":{"name":"King"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-121.234173,47.778881],[-121.119157,47.778881],[-121.11368,47.598142],[-121.11368,47.598142],[-121.38205,47.088787],[-122.417192,47.318818],[-122.395284,47.778881],[-121.234173,47.778881]]],[[[-122.537684,47.357157],[-122.537684,47.400973],[-122.482915,47.510511],[-122.537684,47.357157]]]]}}, -{"type":"Feature","id":"53035","properties":{"name":"Kitsap"},"geometry":{"type":"Polygon","coordinates":[[[-122.482915,47.510511],[-122.537684,47.400973],[-122.800578,47.406449],[-122.948455,47.603619],[-122.751285,47.740543],[-122.482915,47.510511]]]}}, -{"type":"Feature","id":"53037","properties":{"name":"Kittitas"},"geometry":{"type":"Polygon","coordinates":[[[-121.11368,47.598142],[-121.11368,47.598142],[-120.094969,47.264049],[-120.007338,47.220233],[-119.974476,46.738263],[-120.511216,46.738263],[-121.38205,47.088787],[-121.11368,47.598142]]]}}, -{"type":"Feature","id":"53039","properties":{"name":"Klickitat"},"geometry":{"type":"Polygon","coordinates":[[[-119.990907,46.042691],[-119.864937,46.042691],[-119.870414,45.834568],[-120.001861,45.81266],[-120.653617,45.735983],[-120.834356,45.675736],[-120.91651,45.642875],[-121.442296,45.697644],[-121.52445,45.725029],[-121.52445,46.042691],[-119.990907,46.042691]]]}}, -{"type":"Feature","id":"53041","properties":{"name":"Lewis"},"geometry":{"type":"Polygon","coordinates":[[[-123.183963,46.793032],[-123.162056,46.793032],[-122.203591,46.760171],[-121.45325,46.782078],[-121.52445,46.387739],[-122.24193,46.387739],[-123.216825,46.387739],[-123.359225,46.382262],[-123.370179,46.793032],[-123.183963,46.793032]]]}}, -{"type":"Feature","id":"53043","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-118.972196,47.94319],[-118.851704,47.95962],[-118.342348,47.893897],[-117.822039,47.822697],[-117.822039,47.258572],[-117.958962,47.258572],[-118.950288,47.264049],[-118.977673,47.264049],[-118.972196,47.94319]]]}}, -{"type":"Feature","id":"53045","properties":{"name":"Mason"},"geometry":{"type":"Polygon","coordinates":[[[-123.507103,47.515988],[-122.948455,47.603619],[-122.800578,47.406449],[-122.822485,47.192849],[-122.904639,47.15451],[-123.200394,47.08331],[-123.507103,47.515988]]]}}, -{"type":"Feature","id":"53047","properties":{"name":"Okanogan"},"geometry":{"type":"Polygon","coordinates":[[[-118.835273,49.000239],[-118.851704,47.95962],[-118.972196,47.94319],[-118.98315,47.95962],[-119.021489,48.069159],[-119.870414,47.95962],[-120.702909,48.529222],[-120.752202,48.655192],[-120.850787,49.000239],[-118.835273,49.000239]]]}}, -{"type":"Feature","id":"53049","properties":{"name":"Pacific"},"geometry":{"type":"Polygon","coordinates":[[[-124.098612,46.793032],[-123.370179,46.793032],[-123.359225,46.382262],[-123.72618,46.289154],[-124.098612,46.793032]]]}}, -{"type":"Feature","id":"53051","properties":{"name":"Pend Oreille"},"geometry":{"type":"Polygon","coordinates":[[[-117.033359,49.000239],[-117.033359,48.846885],[-117.044313,48.047251],[-117.438653,48.047251],[-117.427699,49.000239],[-117.033359,49.000239]]]}}, -{"type":"Feature","id":"53053","properties":{"name":"Pierce"},"geometry":{"type":"Polygon","coordinates":[[[-122.800578,47.406449],[-122.537684,47.400973],[-122.537684,47.357157],[-122.417192,47.318818],[-121.38205,47.088787],[-121.45325,46.782078],[-122.203591,46.760171],[-122.822485,47.192849],[-122.800578,47.406449]]]}}, -{"type":"Feature","id":"53057","properties":{"name":"Skagit"},"geometry":{"type":"Polygon","coordinates":[[[-122.329561,48.644238],[-120.752202,48.655192],[-120.702909,48.529222],[-121.004141,48.293714],[-121.836636,48.299191],[-122.378853,48.299191],[-122.488392,48.644238],[-122.329561,48.644238]]]}}, -{"type":"Feature","id":"53059","properties":{"name":"Skamania"},"geometry":{"type":"Polygon","coordinates":[[[-121.52445,46.387739],[-121.52445,46.042691],[-121.52445,45.725029],[-121.924267,45.648352],[-122.247407,45.549767],[-122.247407,46.053645],[-122.24193,46.387739],[-121.52445,46.387739]]]}}, -{"type":"Feature","id":"53061","properties":{"name":"Snohomish"},"geometry":{"type":"Polygon","coordinates":[[[-121.836636,48.299191],[-121.004141,48.293714],[-121.119157,47.778881],[-121.234173,47.778881],[-122.395284,47.778881],[-122.395284,48.227991],[-122.406238,48.249898],[-122.378853,48.299191],[-121.836636,48.299191]]]}}, -{"type":"Feature","id":"53063","properties":{"name":"Spokane"},"geometry":{"type":"Polygon","coordinates":[[[-117.537238,48.047251],[-117.438653,48.047251],[-117.044313,48.047251],[-117.044313,47.976051],[-117.038836,47.368111],[-117.038836,47.258572],[-117.822039,47.258572],[-117.822039,47.822697],[-117.537238,48.047251]]]}}, -{"type":"Feature","id":"53065","properties":{"name":"Stevens"},"geometry":{"type":"Polygon","coordinates":[[[-117.427699,49.000239],[-117.438653,48.047251],[-117.537238,48.047251],[-117.822039,47.822697],[-118.342348,47.893897],[-118.139701,48.266329],[-118.194471,49.000239],[-117.427699,49.000239]]]}}, -{"type":"Feature","id":"53067","properties":{"name":"Thurston"},"geometry":{"type":"Polygon","coordinates":[[[-122.904639,47.15451],[-122.822485,47.192849],[-122.203591,46.760171],[-123.162056,46.793032],[-123.200394,47.08331],[-122.904639,47.15451]]]}}, -{"type":"Feature","id":"53069","properties":{"name":"Wahkiakum"},"geometry":{"type":"Polygon","coordinates":[[[-123.359225,46.382262],[-123.216825,46.387739],[-123.211348,46.174138],[-123.364702,46.146753],[-123.545441,46.261769],[-123.72618,46.289154],[-123.359225,46.382262]]]}}, -{"type":"Feature","id":"53071","properties":{"name":"Walla Walla"},"geometry":{"type":"Polygon","coordinates":[[[-118.698349,46.371308],[-118.227332,46.595862],[-117.997301,45.998876],[-118.58881,45.998876],[-118.988627,45.998876],[-119.043396,46.190569],[-118.698349,46.371308]]]}}, -{"type":"Feature","id":"53073","properties":{"name":"Whatcom"},"geometry":{"type":"Polygon","coordinates":[[[-120.850787,49.000239],[-120.752202,48.655192],[-122.329561,48.644238],[-122.488392,48.644238],[-122.756762,49.000239],[-120.850787,49.000239]]]}}, -{"type":"Feature","id":"53075","properties":{"name":"Whitman"},"geometry":{"type":"Polygon","coordinates":[[[-117.822039,47.258572],[-117.038836,47.258572],[-117.038836,47.127126],[-117.038836,46.541093],[-117.038836,46.426077],[-117.230529,46.464416],[-117.849423,46.623247],[-118.216378,46.590385],[-118.210901,46.738263],[-117.958962,47.258572],[-117.822039,47.258572]]]}}, -{"type":"Feature","id":"53077","properties":{"name":"Yakima"},"geometry":{"type":"Polygon","coordinates":[[[-121.38205,47.088787],[-120.511216,46.738263],[-119.974476,46.738263],[-119.875891,46.628724],[-119.864937,46.042691],[-119.990907,46.042691],[-121.52445,46.042691],[-121.52445,46.387739],[-121.45325,46.782078],[-121.38205,47.088787]]]}}, -{"type":"Feature","id":"54001","properties":{"name":"Barbour"},"geometry":{"type":"Polygon","coordinates":[[[-79.976381,39.262239],[-79.894227,39.300578],[-79.812073,39.229378],[-79.823026,39.114362],[-80.08592,38.944577],[-80.22832,39.114362],[-80.168074,39.240331],[-79.976381,39.262239]]]}}, -{"type":"Feature","id":"54003","properties":{"name":"Berkeley"},"geometry":{"type":"Polygon","coordinates":[[[-78.021113,39.61824],[-77.823943,39.492271],[-77.823943,39.492271],[-78.032067,39.262239],[-78.229237,39.393686],[-78.021113,39.61824]]]}}, -{"type":"Feature","id":"54005","properties":{"name":"Boone"},"geometry":{"type":"Polygon","coordinates":[[[-81.756386,38.20519],[-81.455155,37.986112],[-81.564693,37.931343],[-81.515401,37.788942],[-81.608509,37.788942],[-81.931648,38.024451],[-81.833064,38.210667],[-81.756386,38.20519]]]}}, -{"type":"Feature","id":"54007","properties":{"name":"Braxton"},"geometry":{"type":"Polygon","coordinates":[[[-80.606229,38.906238],[-80.458352,38.74193],[-80.650044,38.528329],[-80.677429,38.533806],[-80.880076,38.506421],[-81.03343,38.665253],[-80.984138,38.720022],[-80.606229,38.906238]]]}}, -{"type":"Feature","id":"54009","properties":{"name":"Brooke"},"geometry":{"type":"Polygon","coordinates":[[[-80.518598,40.401443],[-80.518598,40.160457],[-80.682906,40.187842],[-80.633614,40.395966],[-80.518598,40.401443]]]}}, -{"type":"Feature","id":"54011","properties":{"name":"Cabell"},"geometry":{"type":"Polygon","coordinates":[[[-82.265742,38.599529],[-82.216449,38.594052],[-82.057618,38.47356],[-82.046664,38.374975],[-82.265742,38.227097],[-82.506727,38.413313],[-82.28765,38.583099],[-82.265742,38.599529]]]}}, -{"type":"Feature","id":"54013","properties":{"name":"Calhoun"},"geometry":{"type":"Polygon","coordinates":[[[-81.115584,39.037685],[-81.03343,39.0103],[-80.984138,38.720022],[-81.03343,38.665253],[-81.055338,38.643345],[-81.082723,38.610483],[-81.279893,38.917192],[-81.164877,39.032208],[-81.115584,39.037685]]]}}, -{"type":"Feature","id":"54015","properties":{"name":"Clay"},"geometry":{"type":"Polygon","coordinates":[[[-81.055338,38.643345],[-81.03343,38.665253],[-80.880076,38.506421],[-81.2306,38.265436],[-81.192262,38.528329],[-81.082723,38.610483],[-81.055338,38.643345]]]}}, -{"type":"Feature","id":"54017","properties":{"name":"Doddridge"},"geometry":{"type":"Polygon","coordinates":[[[-80.617183,39.448455],[-80.545983,39.426547],[-80.595275,39.169131],[-80.726722,39.097931],[-80.814353,39.108885],[-80.89103,39.295101],[-80.617183,39.448455]]]}}, -{"type":"Feature","id":"54019","properties":{"name":"Fayette"},"geometry":{"type":"Polygon","coordinates":[[[-81.192262,38.232574],[-80.880076,38.101128],[-80.808876,37.871096],[-80.945799,37.821804],[-81.378478,37.969681],[-81.2306,38.265436],[-81.192262,38.232574]]]}}, -{"type":"Feature","id":"54021","properties":{"name":"Gilmer"},"geometry":{"type":"Polygon","coordinates":[[[-80.726722,39.097931],[-80.606229,38.906238],[-80.984138,38.720022],[-81.03343,39.0103],[-80.814353,39.108885],[-80.726722,39.097931]]]}}, -{"type":"Feature","id":"54023","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-78.979578,39.240331],[-79.132932,38.81313],[-79.35201,38.95553],[-79.357487,38.966484],[-79.488933,39.196516],[-79.488933,39.20747],[-79.275332,39.327962],[-78.979578,39.240331]]]}}, -{"type":"Feature","id":"54025","properties":{"name":"Greenbrier"},"geometry":{"type":"Polygon","coordinates":[[[-80.414536,38.254482],[-80.359767,38.227097],[-79.95995,38.062789],[-80.058535,37.95325],[-80.294043,37.690357],[-80.660998,37.734173],[-80.808876,37.871096],[-80.880076,38.101128],[-80.436444,38.265436],[-80.414536,38.254482]]]}}, -{"type":"Feature","id":"54027","properties":{"name":"Hampshire"},"geometry":{"type":"Polygon","coordinates":[[[-78.656438,39.536086],[-78.470222,39.514178],[-78.349729,39.464886],[-78.508561,39.086977],[-78.979578,39.240331],[-78.656438,39.536086]]]}}, -{"type":"Feature","id":"54029","properties":{"name":"Hancock"},"geometry":{"type":"Polygon","coordinates":[[[-80.518598,40.636951],[-80.518598,40.47812],[-80.518598,40.401443],[-80.633614,40.395966],[-80.666475,40.582182],[-80.518598,40.636951]]]}}, -{"type":"Feature","id":"54031","properties":{"name":"Hardy"},"geometry":{"type":"Polygon","coordinates":[[[-78.979578,39.240331],[-78.508561,39.086977],[-78.541422,39.054115],[-78.870039,38.763838],[-78.990532,38.845992],[-79.056255,38.763838],[-79.132932,38.81313],[-78.979578,39.240331]]]}}, -{"type":"Feature","id":"54033","properties":{"name":"Harrison"},"geometry":{"type":"Polygon","coordinates":[[[-80.49669,39.470363],[-80.195458,39.393686],[-80.168074,39.240331],[-80.22832,39.114362],[-80.29952,39.103408],[-80.452875,39.141746],[-80.595275,39.169131],[-80.545983,39.426547],[-80.49669,39.470363]]]}}, -{"type":"Feature","id":"54035","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-81.739956,39.092454],[-81.581124,39.026731],[-81.504447,38.917192],[-81.520878,38.610483],[-81.69614,38.626914],[-81.772817,38.681683],[-81.909741,38.878853],[-81.745433,39.097931],[-81.739956,39.092454]]]}}, -{"type":"Feature","id":"54037","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-77.823943,39.492271],[-77.823943,39.492271],[-77.719881,39.322485],[-77.82942,39.130793],[-78.032067,39.262239],[-77.823943,39.492271]]]}}, -{"type":"Feature","id":"54039","properties":{"name":"Kanawha"},"geometry":{"type":"Polygon","coordinates":[[[-81.69614,38.626914],[-81.69614,38.626914],[-81.520878,38.610483],[-81.192262,38.528329],[-81.2306,38.265436],[-81.2306,38.265436],[-81.378478,37.969681],[-81.455155,37.986112],[-81.756386,38.20519],[-81.833064,38.210667],[-81.915218,38.325682],[-81.69614,38.626914]]]}}, -{"type":"Feature","id":"54041","properties":{"name":"Lewis"},"geometry":{"type":"Polygon","coordinates":[[[-80.452875,39.141746],[-80.29952,39.103408],[-80.392628,38.725499],[-80.458352,38.74193],[-80.606229,38.906238],[-80.726722,39.097931],[-80.595275,39.169131],[-80.452875,39.141746]]]}}, -{"type":"Feature","id":"54043","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-82.046664,38.374975],[-81.915218,38.325682],[-81.833064,38.210667],[-81.931648,38.024451],[-82.189065,37.975158],[-82.30408,37.942297],[-82.265742,38.227097],[-82.046664,38.374975]]]}}, -{"type":"Feature","id":"54045","properties":{"name":"Logan"},"geometry":{"type":"Polygon","coordinates":[[[-81.931648,38.024451],[-81.608509,37.788942],[-81.800202,37.662973],[-82.189065,37.975158],[-81.931648,38.024451]]]}}, -{"type":"Feature","id":"54047","properties":{"name":"McDowell"},"geometry":{"type":"Polygon","coordinates":[[[-81.838541,37.547957],[-81.312754,37.421987],[-81.362047,37.339833],[-81.373001,37.323402],[-81.739956,37.241248],[-81.926172,37.509618],[-81.854971,37.547957],[-81.838541,37.547957]]]}}, -{"type":"Feature","id":"54049","properties":{"name":"Marion"},"geometry":{"type":"Polygon","coordinates":[[[-80.398105,39.634671],[-79.938042,39.453932],[-80.195458,39.393686],[-80.49669,39.470363],[-80.398105,39.634671]]]}}, -{"type":"Feature","id":"54051","properties":{"name":"Marshall"},"geometry":{"type":"Polygon","coordinates":[[[-80.726722,40.034488],[-80.518598,40.018057],[-80.518598,39.963288],[-80.518598,39.722302],[-80.830783,39.722302],[-80.81983,39.848272],[-80.732199,40.034488],[-80.726722,40.034488]]]}}, -{"type":"Feature","id":"54053","properties":{"name":"Mason"},"geometry":{"type":"Polygon","coordinates":[[[-81.909741,38.878853],[-81.772817,38.681683],[-82.057618,38.47356],[-82.216449,38.594052],[-82.101434,38.95553],[-81.909741,38.878853]]]}}, -{"type":"Feature","id":"54055","properties":{"name":"Mercer"},"geometry":{"type":"Polygon","coordinates":[[[-81.126538,37.591772],[-81.093677,37.586295],[-80.858168,37.427464],[-80.978661,37.290541],[-81.225123,37.235771],[-81.362047,37.339833],[-81.312754,37.421987],[-81.219646,37.509618],[-81.126538,37.591772]]]}}, -{"type":"Feature","id":"54057","properties":{"name":"Mineral"},"geometry":{"type":"Polygon","coordinates":[[[-78.738592,39.623717],[-78.656438,39.536086],[-78.979578,39.240331],[-79.275332,39.327962],[-79.067209,39.47584],[-78.738592,39.623717]]]}}, -{"type":"Feature","id":"54059","properties":{"name":"Mingo"},"geometry":{"type":"Polygon","coordinates":[[[-82.30408,37.942297],[-82.189065,37.975158],[-81.800202,37.662973],[-81.854971,37.547957],[-81.926172,37.509618],[-81.969987,37.537003],[-82.145249,37.569865],[-82.331465,37.73965],[-82.413619,37.854665],[-82.30408,37.942297]]]}}, -{"type":"Feature","id":"54061","properties":{"name":"Monongalia"},"geometry":{"type":"Polygon","coordinates":[[[-79.916134,39.722302],[-79.76278,39.722302],[-79.894227,39.437501],[-79.938042,39.453932],[-80.398105,39.634671],[-80.420013,39.722302],[-79.916134,39.722302]]]}}, -{"type":"Feature","id":"54063","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-80.660998,37.734173],[-80.294043,37.690357],[-80.222843,37.630111],[-80.474782,37.421987],[-80.858168,37.427464],[-80.660998,37.734173]]]}}, -{"type":"Feature","id":"54065","properties":{"name":"Morgan"},"geometry":{"type":"Polygon","coordinates":[[[-78.185421,39.694917],[-78.021113,39.61824],[-78.229237,39.393686],[-78.349729,39.464886],[-78.470222,39.514178],[-78.333299,39.634671],[-78.185421,39.694917]]]}}, -{"type":"Feature","id":"54067","properties":{"name":"Nicholas"},"geometry":{"type":"Polygon","coordinates":[[[-80.677429,38.533806],[-80.650044,38.528329],[-80.436444,38.265436],[-80.880076,38.101128],[-81.192262,38.232574],[-81.2306,38.265436],[-81.2306,38.265436],[-80.880076,38.506421],[-80.677429,38.533806]]]}}, -{"type":"Feature","id":"54069","properties":{"name":"Ohio"},"geometry":{"type":"Polygon","coordinates":[[[-80.682906,40.187842],[-80.518598,40.160457],[-80.518598,40.018057],[-80.726722,40.034488],[-80.732199,40.034488],[-80.704814,40.15498],[-80.682906,40.187842]]]}}, -{"type":"Feature","id":"54071","properties":{"name":"Pendleton"},"geometry":{"type":"Polygon","coordinates":[[[-79.35201,38.95553],[-79.132932,38.81313],[-79.056255,38.763838],[-79.22604,38.479037],[-79.313671,38.413313],[-79.647764,38.594052],[-79.625857,38.665253],[-79.35201,38.95553]]]}}, -{"type":"Feature","id":"54073","properties":{"name":"Pleasants"},"geometry":{"type":"Polygon","coordinates":[[[-81.038907,39.470363],[-81.006046,39.34987],[-81.016999,39.34987],[-81.241554,39.267716],[-81.373001,39.344393],[-81.121061,39.459409],[-81.038907,39.470363]]]}}, -{"type":"Feature","id":"54075","properties":{"name":"Pocahontas"},"geometry":{"type":"Polygon","coordinates":[[[-79.625857,38.665253],[-79.647764,38.594052],[-79.795642,38.265436],[-79.95995,38.062789],[-80.359767,38.227097],[-80.244751,38.385929],[-79.625857,38.665253]]]}}, -{"type":"Feature","id":"54077","properties":{"name":"Preston"},"geometry":{"type":"Polygon","coordinates":[[[-79.609426,39.722302],[-79.477979,39.722302],[-79.488933,39.20747],[-79.488933,39.196516],[-79.812073,39.229378],[-79.894227,39.300578],[-79.894227,39.437501],[-79.76278,39.722302],[-79.609426,39.722302]]]}}, -{"type":"Feature","id":"54079","properties":{"name":"Putnam"},"geometry":{"type":"Polygon","coordinates":[[[-81.69614,38.626914],[-81.69614,38.626914],[-81.915218,38.325682],[-82.046664,38.374975],[-82.057618,38.47356],[-81.772817,38.681683],[-81.69614,38.626914]]]}}, -{"type":"Feature","id":"54081","properties":{"name":"Raleigh"},"geometry":{"type":"Polygon","coordinates":[[[-81.564693,37.931343],[-81.455155,37.986112],[-81.378478,37.969681],[-80.945799,37.821804],[-81.093677,37.586295],[-81.126538,37.591772],[-81.219646,37.509618],[-81.515401,37.788942],[-81.564693,37.931343]]]}}, -{"type":"Feature","id":"54083","properties":{"name":"Randolph"},"geometry":{"type":"Polygon","coordinates":[[[-79.757303,39.032208],[-79.357487,38.966484],[-79.35201,38.95553],[-79.625857,38.665253],[-80.244751,38.385929],[-80.277612,38.692637],[-80.08592,38.944577],[-79.823026,39.114362],[-79.757303,39.032208]]]}}, -{"type":"Feature","id":"54085","properties":{"name":"Ritchie"},"geometry":{"type":"Polygon","coordinates":[[[-81.016999,39.34987],[-81.006046,39.34987],[-80.89103,39.295101],[-80.814353,39.108885],[-81.03343,39.0103],[-81.115584,39.037685],[-81.164877,39.032208],[-81.296323,39.185562],[-81.241554,39.267716],[-81.016999,39.34987]]]}}, -{"type":"Feature","id":"54087","properties":{"name":"Roane"},"geometry":{"type":"Polygon","coordinates":[[[-81.433247,38.933623],[-81.279893,38.917192],[-81.082723,38.610483],[-81.192262,38.528329],[-81.520878,38.610483],[-81.504447,38.917192],[-81.433247,38.933623]]]}}, -{"type":"Feature","id":"54089","properties":{"name":"Summers"},"geometry":{"type":"Polygon","coordinates":[[[-80.808876,37.871096],[-80.660998,37.734173],[-80.858168,37.427464],[-80.858168,37.427464],[-81.093677,37.586295],[-80.945799,37.821804],[-80.808876,37.871096]]]}}, -{"type":"Feature","id":"54091","properties":{"name":"Taylor"},"geometry":{"type":"Polygon","coordinates":[[[-79.938042,39.453932],[-79.894227,39.437501],[-79.894227,39.300578],[-79.976381,39.262239],[-80.168074,39.240331],[-80.195458,39.393686],[-79.938042,39.453932]]]}}, -{"type":"Feature","id":"54093","properties":{"name":"Tucker"},"geometry":{"type":"Polygon","coordinates":[[[-79.812073,39.229378],[-79.488933,39.196516],[-79.357487,38.966484],[-79.757303,39.032208],[-79.823026,39.114362],[-79.812073,39.229378]]]}}, -{"type":"Feature","id":"54095","properties":{"name":"Tyler"},"geometry":{"type":"Polygon","coordinates":[[[-80.945799,39.607286],[-80.617183,39.448455],[-80.89103,39.295101],[-81.006046,39.34987],[-81.038907,39.470363],[-81.121061,39.459409],[-81.038907,39.541563],[-80.945799,39.607286]]]}}, -{"type":"Feature","id":"54097","properties":{"name":"Upshur"},"geometry":{"type":"Polygon","coordinates":[[[-80.22832,39.114362],[-80.08592,38.944577],[-80.277612,38.692637],[-80.392628,38.725499],[-80.29952,39.103408],[-80.22832,39.114362]]]}}, -{"type":"Feature","id":"54099","properties":{"name":"Wayne"},"geometry":{"type":"Polygon","coordinates":[[[-82.561497,38.40236],[-82.506727,38.413313],[-82.265742,38.227097],[-82.30408,37.942297],[-82.413619,37.854665],[-82.495773,37.947773],[-82.605312,38.249005],[-82.594358,38.424267],[-82.561497,38.40236]]]}}, -{"type":"Feature","id":"54101","properties":{"name":"Webster"},"geometry":{"type":"Polygon","coordinates":[[[-80.458352,38.74193],[-80.392628,38.725499],[-80.277612,38.692637],[-80.244751,38.385929],[-80.359767,38.227097],[-80.414536,38.254482],[-80.436444,38.265436],[-80.650044,38.528329],[-80.458352,38.74193]]]}}, -{"type":"Feature","id":"54103","properties":{"name":"Wetzel"},"geometry":{"type":"Polygon","coordinates":[[[-80.830783,39.722302],[-80.518598,39.722302],[-80.420013,39.722302],[-80.398105,39.634671],[-80.49669,39.470363],[-80.545983,39.426547],[-80.617183,39.448455],[-80.945799,39.607286],[-80.830783,39.722302]]]}}, -{"type":"Feature","id":"54105","properties":{"name":"Wirt"},"geometry":{"type":"Polygon","coordinates":[[[-81.42777,39.13627],[-81.296323,39.185562],[-81.164877,39.032208],[-81.279893,38.917192],[-81.433247,38.933623],[-81.504447,38.917192],[-81.581124,39.026731],[-81.42777,39.13627]]]}}, -{"type":"Feature","id":"54107","properties":{"name":"Wood"},"geometry":{"type":"Polygon","coordinates":[[[-81.373001,39.344393],[-81.241554,39.267716],[-81.296323,39.185562],[-81.42777,39.13627],[-81.581124,39.026731],[-81.739956,39.092454],[-81.745433,39.097931],[-81.756386,39.180085],[-81.723525,39.218424],[-81.373001,39.344393]]]}}, -{"type":"Feature","id":"54109","properties":{"name":"Wyoming"},"geometry":{"type":"Polygon","coordinates":[[[-81.515401,37.788942],[-81.219646,37.509618],[-81.312754,37.421987],[-81.838541,37.547957],[-81.854971,37.547957],[-81.800202,37.662973],[-81.608509,37.788942],[-81.515401,37.788942]]]}}, -{"type":"Feature","id":"55001","properties":{"name":"Adams"},"geometry":{"type":"Polygon","coordinates":[[[-89.818443,44.251732],[-89.725335,44.246255],[-89.599365,44.246255],[-89.599365,43.983362],[-89.599365,43.643791],[-89.785581,43.638314],[-89.900597,44.251732],[-89.818443,44.251732]]]}}, -{"type":"Feature","id":"55003","properties":{"name":"Ashland"},"geometry":{"type":"Polygon","coordinates":[[[-90.546876,46.584908],[-90.300413,45.982445],[-90.678322,45.982445],[-90.924785,46.15223],[-90.924785,46.584908],[-90.546876,46.584908]]]}}, -{"type":"Feature","id":"55005","properties":{"name":"Barron"},"geometry":{"type":"Polygon","coordinates":[[[-92.157096,45.637398],[-92.031127,45.637398],[-91.538202,45.637398],[-91.543679,45.29235],[-91.664172,45.210196],[-92.157096,45.210196],[-92.157096,45.637398]]]}}, -{"type":"Feature","id":"55007","properties":{"name":"Bayfield"},"geometry":{"type":"Polygon","coordinates":[[[-90.924785,46.584908],[-90.924785,46.15223],[-91.302693,46.157707],[-91.549156,46.157707],[-91.549156,46.754694],[-90.870015,46.962817],[-90.924785,46.584908]]]}}, -{"type":"Feature","id":"55009","properties":{"name":"Brown"},"geometry":{"type":"Polygon","coordinates":[[[-88.235607,44.678933],[-87.989145,44.678933],[-87.76459,44.646072],[-87.76459,44.328409],[-87.885083,44.328409],[-88.043914,44.240778],[-88.191791,44.240778],[-88.246561,44.585825],[-88.241084,44.678933],[-88.235607,44.678933]]]}}, -{"type":"Feature","id":"55011","properties":{"name":"Buffalo"},"geometry":{"type":"Polygon","coordinates":[[[-91.647741,44.596779],[-91.527248,44.596779],[-91.56011,44.027177],[-91.855864,44.191485],[-92.085896,44.405086],[-91.647741,44.596779]]]}}, -{"type":"Feature","id":"55013","properties":{"name":"Burnett"},"geometry":{"type":"Polygon","coordinates":[[[-92.29402,46.157707],[-92.047557,46.157707],[-92.031127,45.637398],[-92.157096,45.637398],[-92.529528,45.730506],[-92.885529,45.642875],[-92.841714,45.730506],[-92.29402,46.157707]]]}}, -{"type":"Feature","id":"55015","properties":{"name":"Calumet"},"geometry":{"type":"Polygon","coordinates":[[[-88.405392,44.246255],[-88.191791,44.240778],[-88.043914,44.240778],[-88.043914,43.890254],[-88.164407,43.890254],[-88.405392,43.939546],[-88.405392,44.246255]]]}}, -{"type":"Feature","id":"55017","properties":{"name":"Chippewa"},"geometry":{"type":"Polygon","coordinates":[[[-91.089093,45.29235],[-90.924785,45.29235],[-90.924785,45.029457],[-90.924785,44.859672],[-91.499863,44.859672],[-91.653218,44.854195],[-91.664172,45.210196],[-91.543679,45.29235],[-91.089093,45.29235]]]}}, -{"type":"Feature","id":"55019","properties":{"name":"Clark"},"geometry":{"type":"Polygon","coordinates":[[[-90.815246,45.029457],[-90.316844,45.034934],[-90.316844,44.68441],[-90.316844,44.426994],[-90.924785,44.596779],[-90.924785,44.859672],[-90.924785,45.029457],[-90.815246,45.029457]]]}}, -{"type":"Feature","id":"55021","properties":{"name":"Columbia"},"geometry":{"type":"Polygon","coordinates":[[[-89.243364,43.643791],[-89.007855,43.632838],[-89.007855,43.282313],[-89.413149,43.293267],[-89.719858,43.293267],[-89.785581,43.638314],[-89.599365,43.643791],[-89.243364,43.643791]]]}}, -{"type":"Feature","id":"55023","properties":{"name":"Crawford"},"geometry":{"type":"Polygon","coordinates":[[[-90.9686,43.424714],[-90.667368,43.424714],[-90.667368,43.172775],[-91.154816,42.986559],[-91.176724,43.079667],[-91.204109,43.424714],[-90.9686,43.424714]]]}}, -{"type":"Feature","id":"55025","properties":{"name":"Dane"},"geometry":{"type":"Polygon","coordinates":[[[-89.413149,43.293267],[-89.007855,43.282313],[-89.007855,43.200159],[-89.013332,42.849635],[-89.051671,42.849635],[-89.369334,42.844158],[-89.84035,42.855112],[-89.84035,43.205636],[-89.719858,43.293267],[-89.413149,43.293267]]]}}, -{"type":"Feature","id":"55027","properties":{"name":"Dodge"},"geometry":{"type":"Polygon","coordinates":[[[-88.887363,43.632838],[-88.399915,43.545207],[-88.416346,43.194682],[-88.536839,43.194682],[-88.991425,43.200159],[-89.007855,43.200159],[-89.007855,43.282313],[-89.007855,43.632838],[-88.887363,43.632838]]]}}, -{"type":"Feature","id":"55029","properties":{"name":"Door"},"geometry":{"type":"Polygon","coordinates":[[[-87.375727,44.673456],[-87.737205,44.678933],[-86.981388,45.297827],[-87.375727,44.673456]]]}}, -{"type":"Feature","id":"55031","properties":{"name":"Douglas"},"geometry":{"type":"Polygon","coordinates":[[[-91.549156,46.754694],[-91.549156,46.157707],[-92.020173,46.157707],[-92.047557,46.157707],[-92.29402,46.157707],[-92.29402,46.415123],[-92.29402,46.661586],[-92.014696,46.705401],[-91.549156,46.754694]]]}}, -{"type":"Feature","id":"55033","properties":{"name":"Dunn"},"geometry":{"type":"Polygon","coordinates":[[[-92.157096,45.210196],[-91.664172,45.210196],[-91.653218,44.854195],[-91.647741,44.68441],[-91.894203,44.68441],[-92.135188,44.68441],[-92.135188,44.859672],[-92.157096,45.210196]]]}}, -{"type":"Feature","id":"55035","properties":{"name":"Eau Claire"},"geometry":{"type":"Polygon","coordinates":[[[-91.499863,44.859672],[-90.924785,44.859672],[-90.924785,44.596779],[-91.16577,44.596779],[-91.286263,44.596779],[-91.527248,44.596779],[-91.647741,44.596779],[-91.647741,44.68441],[-91.653218,44.854195],[-91.499863,44.859672]]]}}, -{"type":"Feature","id":"55037","properties":{"name":"Florence"},"geometry":{"type":"Polygon","coordinates":[[[-88.493023,45.993399],[-88.115114,45.922199],[-88.060345,45.779798],[-88.4273,45.725029],[-88.684716,46.015307],[-88.493023,45.993399]]]}}, -{"type":"Feature","id":"55039","properties":{"name":"Fond du Lac"},"geometry":{"type":"Polygon","coordinates":[[[-88.405392,43.939546],[-88.164407,43.890254],[-88.15893,43.545207],[-88.399915,43.545207],[-88.887363,43.632838],[-88.887363,43.895731],[-88.405392,43.939546]]]}}, -{"type":"Feature","id":"55041","properties":{"name":"Forest"},"geometry":{"type":"Polygon","coordinates":[[[-88.931178,46.075553],[-88.684716,46.015307],[-88.4273,45.725029],[-88.4273,45.374505],[-88.679239,45.379982],[-89.046194,45.462136],[-89.046194,45.894814],[-88.931178,46.075553]]]}}, -{"type":"Feature","id":"55043","properties":{"name":"Grant"},"geometry":{"type":"Polygon","coordinates":[[[-90.552353,43.205636],[-90.43186,43.200159],[-90.426383,42.811297],[-90.426383,42.504588],[-90.639984,42.510065],[-90.8974,42.674373],[-91.154816,42.986559],[-90.667368,43.172775],[-90.552353,43.205636]]]}}, -{"type":"Feature","id":"55045","properties":{"name":"Green"},"geometry":{"type":"Polygon","coordinates":[[[-89.84035,42.855112],[-89.369334,42.844158],[-89.363857,42.499111],[-89.402195,42.499111],[-89.84035,42.504588],[-89.84035,42.811297],[-89.84035,42.855112]]]}}, -{"type":"Feature","id":"55047","properties":{"name":"Green Lake"},"geometry":{"type":"Polygon","coordinates":[[[-88.936655,43.983362],[-88.887363,43.983362],[-88.887363,43.895731],[-88.887363,43.632838],[-89.007855,43.632838],[-89.243364,43.643791],[-89.166687,43.983362],[-88.936655,43.983362]]]}}, -{"type":"Feature","id":"55049","properties":{"name":"Iowa"},"geometry":{"type":"Polygon","coordinates":[[[-90.294936,43.205636],[-90.196352,43.161821],[-89.84035,43.205636],[-89.84035,42.855112],[-89.84035,42.811297],[-90.30589,42.816773],[-90.426383,42.811297],[-90.43186,43.200159],[-90.294936,43.205636]]]}}, -{"type":"Feature","id":"55051","properties":{"name":"Iron"},"geometry":{"type":"Polygon","coordinates":[[[-90.415429,46.568478],[-89.927981,46.300108],[-90.042997,45.982445],[-90.300413,45.982445],[-90.546876,46.584908],[-90.415429,46.568478]]]}}, -{"type":"Feature","id":"55053","properties":{"name":"Jackson"},"geometry":{"type":"Polygon","coordinates":[[[-91.16577,44.596779],[-90.924785,44.596779],[-90.316844,44.426994],[-90.311367,44.246255],[-90.311367,44.153147],[-90.492106,44.158624],[-90.974077,44.070993],[-91.149339,44.081947],[-91.16577,44.596779]]]}}, -{"type":"Feature","id":"55055","properties":{"name":"Jefferson"},"geometry":{"type":"Polygon","coordinates":[[[-88.991425,43.200159],[-88.536839,43.194682],[-88.542316,42.844158],[-88.547792,42.844158],[-88.777824,42.844158],[-89.013332,42.849635],[-89.007855,43.200159],[-88.991425,43.200159]]]}}, -{"type":"Feature","id":"55057","properties":{"name":"Juneau"},"geometry":{"type":"Polygon","coordinates":[[[-90.081336,44.246255],[-89.900597,44.251732],[-89.785581,43.638314],[-90.294936,43.643791],[-90.311367,43.638314],[-90.311367,43.731422],[-90.311367,44.153147],[-90.311367,44.246255],[-90.081336,44.246255]]]}}, -{"type":"Feature","id":"55059","properties":{"name":"Kenosha"},"geometry":{"type":"Polygon","coordinates":[[[-88.027483,42.668896],[-87.808406,42.668896],[-87.802929,42.493634],[-88.202745,42.493634],[-88.219176,42.493634],[-88.306807,42.493634],[-88.306807,42.60865],[-88.027483,42.668896]]]}}, -{"type":"Feature","id":"55061","properties":{"name":"Kewaunee"},"geometry":{"type":"Polygon","coordinates":[[[-87.737205,44.678933],[-87.375727,44.673456],[-87.545512,44.328409],[-87.76459,44.328409],[-87.76459,44.646072],[-87.737205,44.678933]]]}}, -{"type":"Feature","id":"55063","properties":{"name":"La Crosse"},"geometry":{"type":"Polygon","coordinates":[[[-91.176724,44.087424],[-91.149339,44.081947],[-90.974077,44.070993],[-90.908354,43.725946],[-91.258878,43.725946],[-91.286263,43.846438],[-91.423186,43.983362],[-91.176724,44.087424]]]}}, -{"type":"Feature","id":"55065","properties":{"name":"Lafayette"},"geometry":{"type":"Polygon","coordinates":[[[-90.30589,42.816773],[-89.84035,42.811297],[-89.84035,42.504588],[-89.927981,42.504588],[-90.426383,42.504588],[-90.426383,42.811297],[-90.30589,42.816773]]]}}, -{"type":"Feature","id":"55067","properties":{"name":"Langlade"},"geometry":{"type":"Polygon","coordinates":[[[-89.237887,45.467613],[-89.046194,45.462136],[-88.679239,45.379982],[-88.6409,45.117088],[-88.974994,45.117088],[-88.980471,45.029457],[-88.991425,45.029457],[-89.221456,45.029457],[-89.424103,45.117088],[-89.424103,45.467613],[-89.237887,45.467613]]]}}, -{"type":"Feature","id":"55069","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-89.424103,45.467613],[-89.424103,45.117088],[-90.042997,45.122565],[-90.042997,45.379982],[-90.042997,45.555244],[-89.424103,45.467613]]]}}, -{"type":"Feature","id":"55071","properties":{"name":"Manitowoc"},"geometry":{"type":"Polygon","coordinates":[[[-87.885083,44.328409],[-87.76459,44.328409],[-87.545512,44.328409],[-87.731728,43.890254],[-87.770067,43.890254],[-88.043914,43.890254],[-88.043914,44.240778],[-87.885083,44.328409]]]}}, -{"type":"Feature","id":"55073","properties":{"name":"Marathon"},"geometry":{"type":"Polygon","coordinates":[[[-90.196352,45.122565],[-90.042997,45.122565],[-89.424103,45.117088],[-89.221456,45.029457],[-89.221456,44.678933],[-89.347426,44.678933],[-89.845827,44.68441],[-90.207305,44.68441],[-90.316844,44.68441],[-90.316844,45.034934],[-90.196352,45.122565]]]}}, -{"type":"Feature","id":"55075","properties":{"name":"Marinette"},"geometry":{"type":"Polygon","coordinates":[[[-88.060345,45.779798],[-87.846744,45.725029],[-87.589328,45.095181],[-87.76459,44.963734],[-88.4273,45.374505],[-88.4273,45.725029],[-88.060345,45.779798]]]}}, -{"type":"Feature","id":"55077","properties":{"name":"Marquette"},"geometry":{"type":"Polygon","coordinates":[[[-89.166687,43.983362],[-89.243364,43.643791],[-89.599365,43.643791],[-89.599365,43.983362],[-89.166687,43.983362]]]}}, -{"type":"Feature","id":"55078","properties":{"name":"Menominee"},"geometry":{"type":"Polygon","coordinates":[[[-88.974994,45.117088],[-88.6409,45.117088],[-88.487546,44.854195],[-88.980471,45.029457],[-88.974994,45.117088]]]}}, -{"type":"Feature","id":"55079","properties":{"name":"Milwaukee"},"geometry":{"type":"Polygon","coordinates":[[[-87.972714,43.194682],[-87.89056,43.194682],[-87.824836,42.844158],[-87.956283,42.844158],[-88.071299,42.844158],[-88.065822,43.194682],[-87.972714,43.194682]]]}}, -{"type":"Feature","id":"55081","properties":{"name":"Monroe"},"geometry":{"type":"Polygon","coordinates":[[[-90.492106,44.158624],[-90.311367,44.153147],[-90.311367,43.731422],[-90.908354,43.725946],[-90.974077,44.070993],[-90.492106,44.158624]]]}}, -{"type":"Feature","id":"55083","properties":{"name":"Oconto"},"geometry":{"type":"Polygon","coordinates":[[[-88.4273,45.374505],[-87.76459,44.963734],[-87.989145,44.678933],[-88.235607,44.678933],[-88.241084,44.678933],[-88.487546,44.854195],[-88.6409,45.117088],[-88.679239,45.379982],[-88.4273,45.374505]]]}}, -{"type":"Feature","id":"55085","properties":{"name":"Oneida"},"geometry":{"type":"Polygon","coordinates":[[[-89.298133,45.872906],[-89.046194,45.894814],[-89.046194,45.462136],[-89.237887,45.467613],[-89.424103,45.467613],[-90.042997,45.555244],[-90.042997,45.894814],[-89.298133,45.872906]]]}}, -{"type":"Feature","id":"55087","properties":{"name":"Outagamie"},"geometry":{"type":"Polygon","coordinates":[[[-88.575177,44.591302],[-88.246561,44.585825],[-88.191791,44.240778],[-88.405392,44.246255],[-88.471115,44.246255],[-88.739485,44.240778],[-88.608039,44.591302],[-88.575177,44.591302]]]}}, -{"type":"Feature","id":"55089","properties":{"name":"Ozaukee"},"geometry":{"type":"Polygon","coordinates":[[[-87.923421,43.545207],[-87.791975,43.545207],[-87.89056,43.194682],[-87.972714,43.194682],[-88.065822,43.194682],[-88.038437,43.53973],[-87.923421,43.545207]]]}}, -{"type":"Feature","id":"55091","properties":{"name":"Pepin"},"geometry":{"type":"Polygon","coordinates":[[[-91.894203,44.68441],[-91.647741,44.68441],[-91.647741,44.596779],[-92.085896,44.405086],[-92.244727,44.454379],[-92.315927,44.54201],[-92.135188,44.68441],[-91.894203,44.68441]]]}}, -{"type":"Feature","id":"55093","properties":{"name":"Pierce"},"geometry":{"type":"Polygon","coordinates":[[[-92.600728,44.865149],[-92.135188,44.859672],[-92.135188,44.68441],[-92.315927,44.54201],[-92.732175,44.711795],[-92.803375,44.744656],[-92.770513,44.859672],[-92.600728,44.865149]]]}}, -{"type":"Feature","id":"55095","properties":{"name":"Polk"},"geometry":{"type":"Polygon","coordinates":[[[-92.529528,45.730506],[-92.157096,45.637398],[-92.157096,45.210196],[-92.650021,45.210196],[-92.75956,45.210196],[-92.743129,45.297827],[-92.885529,45.642875],[-92.529528,45.730506]]]}}, -{"type":"Feature","id":"55097","properties":{"name":"Portage"},"geometry":{"type":"Polygon","coordinates":[[[-89.347426,44.678933],[-89.221456,44.678933],[-89.226933,44.246255],[-89.599365,44.246255],[-89.725335,44.246255],[-89.845827,44.68441],[-89.347426,44.678933]]]}}, -{"type":"Feature","id":"55099","properties":{"name":"Price"},"geometry":{"type":"Polygon","coordinates":[[[-90.300413,45.982445],[-90.042997,45.982445],[-90.042997,45.894814],[-90.042997,45.555244],[-90.042997,45.379982],[-90.168967,45.379982],[-90.678322,45.379982],[-90.678322,45.637398],[-90.678322,45.982445],[-90.300413,45.982445]]]}}, -{"type":"Feature","id":"55101","properties":{"name":"Racine"},"geometry":{"type":"Polygon","coordinates":[[[-87.956283,42.844158],[-87.824836,42.844158],[-87.808406,42.668896],[-88.027483,42.668896],[-88.306807,42.60865],[-88.306807,42.844158],[-88.071299,42.844158],[-87.956283,42.844158]]]}}, -{"type":"Feature","id":"55103","properties":{"name":"Richland"},"geometry":{"type":"Polygon","coordinates":[[[-90.190875,43.55616],[-90.196352,43.161821],[-90.294936,43.205636],[-90.43186,43.200159],[-90.552353,43.205636],[-90.667368,43.172775],[-90.667368,43.424714],[-90.311367,43.55616],[-90.190875,43.55616]]]}}, -{"type":"Feature","id":"55105","properties":{"name":"Rock"},"geometry":{"type":"Polygon","coordinates":[[[-89.051671,42.849635],[-89.013332,42.849635],[-88.777824,42.844158],[-88.777824,42.493634],[-88.942132,42.493634],[-89.363857,42.499111],[-89.369334,42.844158],[-89.051671,42.849635]]]}}, -{"type":"Feature","id":"55107","properties":{"name":"Rusk"},"geometry":{"type":"Polygon","coordinates":[[[-90.678322,45.637398],[-90.678322,45.379982],[-90.924785,45.29235],[-91.089093,45.29235],[-91.543679,45.29235],[-91.538202,45.637398],[-90.678322,45.637398]]]}}, -{"type":"Feature","id":"55109","properties":{"name":"St. Croix"},"geometry":{"type":"Polygon","coordinates":[[[-92.650021,45.210196],[-92.157096,45.210196],[-92.135188,44.859672],[-92.600728,44.865149],[-92.770513,44.859672],[-92.75956,45.210196],[-92.650021,45.210196]]]}}, -{"type":"Feature","id":"55111","properties":{"name":"Sauk"},"geometry":{"type":"Polygon","coordinates":[[[-90.294936,43.643791],[-89.785581,43.638314],[-89.719858,43.293267],[-89.84035,43.205636],[-90.196352,43.161821],[-90.190875,43.55616],[-90.311367,43.55616],[-90.311367,43.638314],[-90.294936,43.643791]]]}}, -{"type":"Feature","id":"55113","properties":{"name":"Sawyer"},"geometry":{"type":"Polygon","coordinates":[[[-91.302693,46.157707],[-90.924785,46.15223],[-90.678322,45.982445],[-90.678322,45.637398],[-91.538202,45.637398],[-91.549156,46.157707],[-91.302693,46.157707]]]}}, -{"type":"Feature","id":"55115","properties":{"name":"Shawano"},"geometry":{"type":"Polygon","coordinates":[[[-88.991425,45.029457],[-88.980471,45.029457],[-88.487546,44.854195],[-88.241084,44.678933],[-88.246561,44.585825],[-88.575177,44.591302],[-88.608039,44.591302],[-89.221456,44.678933],[-89.221456,45.029457],[-88.991425,45.029457]]]}}, -{"type":"Feature","id":"55117","properties":{"name":"Sheboygan"},"geometry":{"type":"Polygon","coordinates":[[[-87.770067,43.890254],[-87.731728,43.890254],[-87.791975,43.545207],[-87.923421,43.545207],[-88.038437,43.53973],[-88.15893,43.545207],[-88.164407,43.890254],[-88.043914,43.890254],[-87.770067,43.890254]]]}}, -{"type":"Feature","id":"55119","properties":{"name":"Taylor"},"geometry":{"type":"Polygon","coordinates":[[[-90.168967,45.379982],[-90.042997,45.379982],[-90.042997,45.122565],[-90.196352,45.122565],[-90.316844,45.034934],[-90.815246,45.029457],[-90.924785,45.029457],[-90.924785,45.29235],[-90.678322,45.379982],[-90.168967,45.379982]]]}}, -{"type":"Feature","id":"55121","properties":{"name":"Trempealeau"},"geometry":{"type":"Polygon","coordinates":[[[-91.286263,44.596779],[-91.16577,44.596779],[-91.149339,44.081947],[-91.176724,44.087424],[-91.423186,43.983362],[-91.56011,44.027177],[-91.527248,44.596779],[-91.286263,44.596779]]]}}, -{"type":"Feature","id":"55123","properties":{"name":"Vernon"},"geometry":{"type":"Polygon","coordinates":[[[-90.311367,43.731422],[-90.311367,43.638314],[-90.311367,43.55616],[-90.667368,43.424714],[-90.9686,43.424714],[-91.204109,43.424714],[-91.215062,43.501391],[-91.258878,43.725946],[-90.908354,43.725946],[-90.311367,43.731422]]]}}, -{"type":"Feature","id":"55125","properties":{"name":"Vilas"},"geometry":{"type":"Polygon","coordinates":[[[-89.927981,46.300108],[-88.991425,46.097461],[-88.931178,46.075553],[-89.046194,45.894814],[-89.298133,45.872906],[-90.042997,45.894814],[-90.042997,45.982445],[-89.927981,46.300108]]]}}, -{"type":"Feature","id":"55127","properties":{"name":"Walworth"},"geometry":{"type":"Polygon","coordinates":[[[-88.547792,42.844158],[-88.542316,42.844158],[-88.306807,42.844158],[-88.306807,42.60865],[-88.306807,42.493634],[-88.706624,42.493634],[-88.777824,42.493634],[-88.777824,42.844158],[-88.547792,42.844158]]]}}, -{"type":"Feature","id":"55129","properties":{"name":"Washburn"},"geometry":{"type":"Polygon","coordinates":[[[-92.020173,46.157707],[-91.549156,46.157707],[-91.538202,45.637398],[-92.031127,45.637398],[-92.047557,46.157707],[-92.020173,46.157707]]]}}, -{"type":"Feature","id":"55131","properties":{"name":"Washington"},"geometry":{"type":"Polygon","coordinates":[[[-88.399915,43.545207],[-88.15893,43.545207],[-88.038437,43.53973],[-88.065822,43.194682],[-88.416346,43.194682],[-88.399915,43.545207]]]}}, -{"type":"Feature","id":"55133","properties":{"name":"Waukesha"},"geometry":{"type":"Polygon","coordinates":[[[-88.536839,43.194682],[-88.416346,43.194682],[-88.065822,43.194682],[-88.071299,42.844158],[-88.306807,42.844158],[-88.542316,42.844158],[-88.536839,43.194682]]]}}, -{"type":"Feature","id":"55135","properties":{"name":"Waupaca"},"geometry":{"type":"Polygon","coordinates":[[[-89.221456,44.678933],[-88.608039,44.591302],[-88.739485,44.240778],[-88.887363,44.240778],[-89.226933,44.246255],[-89.221456,44.678933]]]}}, -{"type":"Feature","id":"55137","properties":{"name":"Waushara"},"geometry":{"type":"Polygon","coordinates":[[[-89.599365,44.246255],[-89.226933,44.246255],[-88.887363,44.240778],[-88.887363,43.983362],[-88.936655,43.983362],[-89.166687,43.983362],[-89.599365,43.983362],[-89.599365,44.246255]]]}}, -{"type":"Feature","id":"55139","properties":{"name":"Winnebago"},"geometry":{"type":"Polygon","coordinates":[[[-88.471115,44.246255],[-88.405392,44.246255],[-88.405392,43.939546],[-88.887363,43.895731],[-88.887363,43.983362],[-88.887363,44.240778],[-88.739485,44.240778],[-88.471115,44.246255]]]}}, -{"type":"Feature","id":"55141","properties":{"name":"Wood"},"geometry":{"type":"Polygon","coordinates":[[[-90.207305,44.68441],[-89.845827,44.68441],[-89.725335,44.246255],[-89.818443,44.251732],[-89.900597,44.251732],[-90.081336,44.246255],[-90.311367,44.246255],[-90.316844,44.426994],[-90.316844,44.68441],[-90.207305,44.68441]]]}}, -{"type":"Feature","id":"56001","properties":{"name":"Albany"},"geometry":{"type":"Polygon","coordinates":[[[-106.074002,42.433388],[-105.285322,42.433388],[-105.279845,41.655662],[-105.279845,40.998429],[-106.189017,40.998429],[-106.320464,40.998429],[-106.068525,41.392769],[-106.074002,42.433388]]]}}, -{"type":"Feature","id":"56003","properties":{"name":"Big Horn"},"geometry":{"type":"Polygon","coordinates":[[[-107.914254,45.002073],[-107.372036,44.55844],[-107.147482,44.164101],[-108.549579,44.169578],[-108.620779,45.002073],[-108.248347,45.002073],[-107.914254,45.002073]]]}}, -{"type":"Feature","id":"56005","properties":{"name":"Campbell"},"geometry":{"type":"Polygon","coordinates":[[[-106.024709,44.991119],[-105.088152,45.002073],[-105.077198,44.175055],[-105.077198,43.495914],[-106.019232,43.495914],[-106.008278,44.563917],[-106.024709,44.991119]]]}}, -{"type":"Feature","id":"56007","properties":{"name":"Carbon"},"geometry":{"type":"Polygon","coordinates":[[[-107.037943,42.433388],[-106.074002,42.433388],[-106.074002,42.433388],[-106.068525,41.392769],[-106.320464,40.998429],[-106.857204,41.003906],[-107.317267,41.003906],[-107.919731,41.003906],[-107.930684,41.661139],[-107.50896,41.655662],[-107.525391,42.263602],[-107.525391,42.433388],[-107.037943,42.433388]]]}}, -{"type":"Feature","id":"56009","properties":{"name":"Converse"},"geometry":{"type":"Polygon","coordinates":[[[-104.901936,43.501391],[-104.890983,42.60865],[-105.285322,42.433388],[-106.074002,42.433388],[-106.074002,42.433388],[-106.079479,43.495914],[-106.019232,43.495914],[-105.077198,43.495914],[-104.901936,43.501391]]]}}, -{"type":"Feature","id":"56011","properties":{"name":"Crook"},"geometry":{"type":"Polygon","coordinates":[[[-105.088152,45.002073],[-105.03886,45.002073],[-104.058488,44.996596],[-104.058488,44.569394],[-104.053011,44.180532],[-104.392581,44.180532],[-105.077198,44.175055],[-105.088152,45.002073]]]}}, -{"type":"Feature","id":"56013","properties":{"name":"Fremont"},"geometry":{"type":"Polygon","coordinates":[[[-110.055737,44.010746],[-109.310873,43.813577],[-108.335978,43.457575],[-107.596591,43.501391],[-107.536345,43.501391],[-107.525391,42.433388],[-107.525391,42.263602],[-109.042503,42.263602],[-109.075365,42.690804],[-110.05026,43.463052],[-110.055737,44.010746]]]}}, -{"type":"Feature","id":"56015","properties":{"name":"Goshen"},"geometry":{"type":"Polygon","coordinates":[[[-104.053011,42.614127],[-104.053011,42.000709],[-104.053011,41.699478],[-104.053011,41.562554],[-104.655474,41.655662],[-104.655474,42.60865],[-104.053011,42.614127]]]}}, -{"type":"Feature","id":"56017","properties":{"name":"Hot Springs"},"geometry":{"type":"Polygon","coordinates":[[[-108.527671,44.081947],[-107.596591,43.501391],[-108.335978,43.457575],[-109.310873,43.813577],[-108.549579,44.081947],[-108.527671,44.081947]]]}}, -{"type":"Feature","id":"56019","properties":{"name":"Johnson"},"geometry":{"type":"Polygon","coordinates":[[[-106.008278,44.563917],[-106.019232,43.495914],[-106.079479,43.495914],[-107.109143,43.501391],[-107.147482,44.164101],[-107.372036,44.55844],[-106.008278,44.563917]]]}}, -{"type":"Feature","id":"56021","properties":{"name":"Laramie"},"geometry":{"type":"Polygon","coordinates":[[[-105.279845,41.655662],[-104.655474,41.655662],[-104.053011,41.562554],[-104.053011,41.392769],[-104.053011,41.003906],[-104.945752,40.998429],[-105.279845,40.998429],[-105.279845,41.655662]]]}}, -{"type":"Feature","id":"56023","properties":{"name":"Lincoln"},"geometry":{"type":"Polygon","coordinates":[[[-111.047063,43.315175],[-110.576047,43.233021],[-110.543185,42.280033],[-110.055737,42.269079],[-110.05026,41.578985],[-111.047063,41.578985],[-111.047063,42.000709],[-111.047063,42.515542],[-111.041587,43.01942],[-111.047063,43.315175]]]}}, -{"type":"Feature","id":"56025","properties":{"name":"Natrona"},"geometry":{"type":"Polygon","coordinates":[[[-107.536345,43.501391],[-107.109143,43.501391],[-106.079479,43.495914],[-106.074002,42.433388],[-107.037943,42.433388],[-107.525391,42.433388],[-107.536345,43.501391]]]}}, -{"type":"Feature","id":"56027","properties":{"name":"Niobrara"},"geometry":{"type":"Polygon","coordinates":[[[-104.053011,43.501391],[-104.053011,43.479483],[-104.053011,43.002989],[-104.053011,42.614127],[-104.655474,42.60865],[-104.890983,42.60865],[-104.901936,43.501391],[-104.053011,43.501391]]]}}, -{"type":"Feature","id":"56029","properties":{"name":"Park"},"geometry":{"type":"Polygon","coordinates":[[[-109.798321,45.002073],[-108.620779,45.002073],[-108.549579,44.169578],[-108.549579,44.081947],[-109.310873,43.813577],[-110.055737,44.010746],[-110.3734,44.580348],[-111.058017,44.667979],[-111.041587,45.002073],[-109.798321,45.002073]]]}}, -{"type":"Feature","id":"56031","properties":{"name":"Platte"},"geometry":{"type":"Polygon","coordinates":[[[-104.655474,42.60865],[-104.655474,41.655662],[-105.279845,41.655662],[-105.285322,42.433388],[-104.890983,42.60865],[-104.655474,42.60865]]]}}, -{"type":"Feature","id":"56033","properties":{"name":"Sheridan"},"geometry":{"type":"Polygon","coordinates":[[[-107.914254,45.002073],[-106.265695,44.991119],[-106.024709,44.991119],[-106.008278,44.563917],[-107.372036,44.55844],[-107.914254,45.002073]]]}}, -{"type":"Feature","id":"56035","properties":{"name":"Sublette"},"geometry":{"type":"Polygon","coordinates":[[[-110.05026,43.463052],[-109.075365,42.690804],[-109.042503,42.263602],[-110.055737,42.269079],[-110.543185,42.280033],[-110.576047,43.233021],[-110.05026,43.463052]]]}}, -{"type":"Feature","id":"56037","properties":{"name":"Sweetwater"},"geometry":{"type":"Polygon","coordinates":[[[-110.055737,42.269079],[-109.042503,42.263602],[-107.525391,42.263602],[-107.50896,41.655662],[-107.930684,41.661139],[-107.919731,41.003906],[-109.04798,40.998429],[-109.677828,40.998429],[-110.000968,40.998429],[-110.05026,40.998429],[-110.05026,41.578985],[-110.055737,42.269079]]]}}, -{"type":"Feature","id":"56039","properties":{"name":"Teton"},"geometry":{"type":"Polygon","coordinates":[[[-111.058017,44.667979],[-110.3734,44.580348],[-110.055737,44.010746],[-110.05026,43.463052],[-110.576047,43.233021],[-111.047063,43.315175],[-111.047063,43.501391],[-111.047063,43.983362],[-111.047063,44.476286],[-111.058017,44.667979]]]}}, -{"type":"Feature","id":"56041","properties":{"name":"Uinta"},"geometry":{"type":"Polygon","coordinates":[[[-111.047063,41.578985],[-110.05026,41.578985],[-110.05026,40.998429],[-111.047063,40.998429],[-111.047063,41.250368],[-111.047063,41.578985]]]}}, -{"type":"Feature","id":"56043","properties":{"name":"Washakie"},"geometry":{"type":"Polygon","coordinates":[[[-107.147482,44.164101],[-107.109143,43.501391],[-107.536345,43.501391],[-107.596591,43.501391],[-108.527671,44.081947],[-108.549579,44.081947],[-108.549579,44.169578],[-107.147482,44.164101]]]}}, -{"type":"Feature","id":"56045","properties":{"name":"Weston"},"geometry":{"type":"Polygon","coordinates":[[[-104.392581,44.180532],[-104.053011,44.180532],[-104.053011,44.142193],[-104.053011,43.851915],[-104.053011,43.501391],[-104.901936,43.501391],[-105.077198,43.495914],[-105.077198,44.175055],[-104.392581,44.180532]]]}}, -{"type":"Feature","id":"72001","properties":{"name":"Adjuntas"},"geometry":{"type":"Polygon","coordinates":[[[-66.722185,18.219834],[-66.672893,18.154111],[-66.6948,18.132203],[-66.716708,18.132203],[-66.771478,18.13768],[-66.798862,18.132203],[-66.826247,18.170542],[-66.815293,18.230788],[-66.722185,18.219834]]]}}, -{"type":"Feature","id":"72003","properties":{"name":"Aguada"},"geometry":{"type":"Polygon","coordinates":[[[-67.16034,18.417004],[-67.132956,18.389619],[-67.127479,18.318419],[-67.182248,18.312942],[-67.237017,18.373189],[-67.16034,18.417004]]]}}, -{"type":"Feature","id":"72005","properties":{"name":"Aguadilla"},"geometry":{"type":"Polygon","coordinates":[[[-67.105571,18.515589],[-67.056278,18.46082],[-67.132956,18.389619],[-67.16034,18.417004],[-67.105571,18.515589],[-67.105571,18.515589]]]}}, -{"type":"Feature","id":"72007","properties":{"name":"Aguas Buenas"},"geometry":{"type":"Polygon","coordinates":[[[-66.064952,18.301988],[-66.119722,18.20888],[-66.147106,18.230788],[-66.169014,18.225311],[-66.190922,18.258173],[-66.141629,18.280081],[-66.081383,18.296511],[-66.064952,18.301988]]]}}, -{"type":"Feature","id":"72009","properties":{"name":"Aibonito"},"geometry":{"type":"Polygon","coordinates":[[[-66.278553,18.176019],[-66.240214,18.181496],[-66.218307,18.143157],[-66.223784,18.093865],[-66.256645,18.077434],[-66.316892,18.154111],[-66.278553,18.176019]]]}}, -{"type":"Feature","id":"72011","properties":{"name":"Añasco"},"geometry":{"type":"Polygon","coordinates":[[[-67.122002,18.323896],[-67.050802,18.307465],[-67.039848,18.291034],[-67.083663,18.252696],[-67.16034,18.274604],[-67.187725,18.269127],[-67.226064,18.296511],[-67.182248,18.312942],[-67.127479,18.318419],[-67.122002,18.323896]]]}}, -{"type":"Feature","id":"72013","properties":{"name":"Arecibo"},"geometry":{"type":"Polygon","coordinates":[[[-66.585262,18.482727],[-66.585262,18.482727],[-66.590739,18.389619],[-66.590739,18.340327],[-66.607169,18.329373],[-66.711231,18.312942],[-66.771478,18.323896],[-66.766001,18.482727],[-66.585262,18.482727]]]}}, -{"type":"Feature","id":"72015","properties":{"name":"Arroyo"},"geometry":{"type":"Polygon","coordinates":[[[-66.059475,18.039095],[-66.021137,17.978849],[-66.070429,17.967895],[-66.081383,18.033618],[-66.059475,18.039095]]]}}, -{"type":"Feature","id":"72017","properties":{"name":"Barceloneta"},"geometry":{"type":"Polygon","coordinates":[[[-66.585262,18.482727],[-66.585262,18.482727],[-66.535969,18.482727],[-66.541446,18.40605],[-66.590739,18.389619],[-66.585262,18.482727]]]}}, -{"type":"Feature","id":"72019","properties":{"name":"Barranquitas"},"geometry":{"type":"Polygon","coordinates":[[[-66.311415,18.247219],[-66.267599,18.247219],[-66.240214,18.186973],[-66.240214,18.181496],[-66.278553,18.176019],[-66.316892,18.154111],[-66.371661,18.176019],[-66.349753,18.241742],[-66.311415,18.247219]]]}}, -{"type":"Feature","id":"72021","properties":{"name":"Bayamón"},"geometry":{"type":"Polygon","coordinates":[[[-66.169014,18.433435],[-66.130676,18.422481],[-66.141629,18.280081],[-66.190922,18.258173],[-66.207353,18.274604],[-66.207353,18.318419],[-66.196399,18.389619],[-66.169014,18.433435]]]}}, -{"type":"Feature","id":"72023","properties":{"name":"Cabo Rojo"},"geometry":{"type":"Polygon","coordinates":[[[-67.182248,18.170542],[-67.16034,18.154111],[-67.100094,18.104819],[-67.111048,18.055526],[-67.111048,17.945987],[-67.182248,18.170542]]]}}, -{"type":"Feature","id":"72025","properties":{"name":"Caguas"},"geometry":{"type":"Polygon","coordinates":[[[-66.021137,18.307465],[-65.999229,18.20888],[-66.053998,18.115772],[-66.097814,18.170542],[-66.119722,18.20888],[-66.064952,18.301988],[-66.043044,18.312942],[-66.021137,18.307465]]]}}, -{"type":"Feature","id":"72027","properties":{"name":"Camuy"},"geometry":{"type":"Polygon","coordinates":[[[-66.837201,18.488204],[-66.826247,18.340327],[-66.89197,18.367712],[-66.897447,18.367712],[-66.902924,18.482727],[-66.837201,18.488204]]]}}, -{"type":"Feature","id":"72029","properties":{"name":"Canóvanas"},"geometry":{"type":"Polygon","coordinates":[[[-65.911598,18.400573],[-65.867782,18.378666],[-65.834921,18.274604],[-65.851352,18.252696],[-65.917075,18.269127],[-65.917075,18.400573],[-65.911598,18.400573]]]}}, -{"type":"Feature","id":"72031","properties":{"name":"Carolina"},"geometry":{"type":"Polygon","coordinates":[[[-65.993752,18.46082],[-65.917075,18.400573],[-65.917075,18.269127],[-65.94446,18.291034],[-65.999229,18.378666],[-66.037568,18.449866],[-65.993752,18.46082]]]}}, -{"type":"Feature","id":"72033","properties":{"name":"Cataño"},"geometry":{"type":"Polygon","coordinates":[[[-66.125199,18.46082],[-66.108768,18.438912],[-66.130676,18.422481],[-66.130676,18.422481],[-66.169014,18.433435],[-66.141629,18.46082],[-66.125199,18.46082]]]}}, -{"type":"Feature","id":"72035","properties":{"name":"Cayey"},"geometry":{"type":"Polygon","coordinates":[[[-66.097814,18.159588],[-66.097814,18.170542],[-66.053998,18.115772],[-66.053998,18.110295],[-66.053998,18.104819],[-66.075906,18.104819],[-66.163537,18.050049],[-66.223784,18.093865],[-66.218307,18.143157],[-66.097814,18.159588]]]}}, -{"type":"Feature","id":"72037","properties":{"name":"Ceiba"},"geometry":{"type":"Polygon","coordinates":[[[-65.752767,18.296511],[-65.632274,18.285558],[-65.659659,18.20888],[-65.769197,18.280081],[-65.758244,18.291034],[-65.752767,18.296511]]]}}, -{"type":"Feature","id":"72039","properties":{"name":"Ciales"},"geometry":{"type":"Polygon","coordinates":[[[-66.475723,18.367712],[-66.464769,18.373189],[-66.453815,18.258173],[-66.541446,18.165065],[-66.568831,18.296511],[-66.607169,18.329373],[-66.590739,18.340327],[-66.535969,18.351281],[-66.475723,18.367712]]]}}, -{"type":"Feature","id":"72041","properties":{"name":"Cidra"},"geometry":{"type":"Polygon","coordinates":[[[-66.147106,18.230788],[-66.119722,18.20888],[-66.097814,18.170542],[-66.097814,18.159588],[-66.218307,18.143157],[-66.240214,18.181496],[-66.240214,18.186973],[-66.169014,18.225311],[-66.147106,18.230788]]]}}, -{"type":"Feature","id":"72043","properties":{"name":"Coamo"},"geometry":{"type":"Polygon","coordinates":[[[-66.371661,18.176019],[-66.316892,18.154111],[-66.256645,18.077434],[-66.333322,18.017187],[-66.382615,18.039095],[-66.42643,18.044572],[-66.431907,18.082911],[-66.442861,18.176019],[-66.371661,18.176019]]]}}, -{"type":"Feature","id":"72045","properties":{"name":"Comerío"},"geometry":{"type":"Polygon","coordinates":[[[-66.207353,18.274604],[-66.190922,18.258173],[-66.169014,18.225311],[-66.240214,18.186973],[-66.267599,18.247219],[-66.207353,18.274604]]]}}, -{"type":"Feature","id":"72047","properties":{"name":"Corozal"},"geometry":{"type":"Polygon","coordinates":[[[-66.305938,18.367712],[-66.278553,18.329373],[-66.311415,18.247219],[-66.349753,18.241742],[-66.377138,18.296511],[-66.366184,18.33485],[-66.316892,18.367712],[-66.305938,18.367712]]]}}, -{"type":"Feature","id":"72051","properties":{"name":"Dorado"},"geometry":{"type":"Polygon","coordinates":[[[-66.196399,18.466297],[-66.251168,18.395096],[-66.305938,18.384142],[-66.316892,18.47725],[-66.196399,18.466297]]]}}, -{"type":"Feature","id":"72053","properties":{"name":"Fajardo"},"geometry":{"type":"Polygon","coordinates":[[[-65.632274,18.285558],[-65.752767,18.296511],[-65.670613,18.362235],[-65.632274,18.285558]]]}}, -{"type":"Feature","id":"72054","properties":{"name":"Florida"},"geometry":{"type":"Polygon","coordinates":[[[-66.541446,18.400573],[-66.535969,18.351281],[-66.590739,18.340327],[-66.590739,18.389619],[-66.541446,18.40605],[-66.541446,18.400573]]]}}, -{"type":"Feature","id":"72055","properties":{"name":"Guánica"},"geometry":{"type":"Polygon","coordinates":[[[-66.957694,18.033618],[-66.886493,18.022664],[-66.859109,17.956941],[-66.979601,17.951464],[-66.957694,18.033618]]]}}, -{"type":"Feature","id":"72057","properties":{"name":"Guayama"},"geometry":{"type":"Polygon","coordinates":[[[-66.075906,18.104819],[-66.053998,18.104819],[-66.081383,18.033618],[-66.070429,17.967895],[-66.207353,17.962418],[-66.163537,18.050049],[-66.075906,18.104819]]]}}, -{"type":"Feature","id":"72059","properties":{"name":"Guayanilla"},"geometry":{"type":"Polygon","coordinates":[[[-66.798862,18.132203],[-66.771478,18.13768],[-66.755047,18.000757],[-66.853632,17.956941],[-66.798862,18.132203]]]}}, -{"type":"Feature","id":"72061","properties":{"name":"Guaynabo"},"geometry":{"type":"Polygon","coordinates":[[[-66.130676,18.422481],[-66.108768,18.438912],[-66.081383,18.296511],[-66.141629,18.280081],[-66.130676,18.422481],[-66.130676,18.422481]]]}}, -{"type":"Feature","id":"72063","properties":{"name":"Gurabo"},"geometry":{"type":"Polygon","coordinates":[[[-65.982798,18.312942],[-65.94446,18.291034],[-65.917075,18.269127],[-65.949936,18.230788],[-65.966367,18.230788],[-65.999229,18.20888],[-66.021137,18.307465],[-65.982798,18.312942]]]}}, -{"type":"Feature","id":"72065","properties":{"name":"Hatillo"},"geometry":{"type":"Polygon","coordinates":[[[-66.766001,18.482727],[-66.771478,18.323896],[-66.826247,18.323896],[-66.826247,18.340327],[-66.837201,18.488204],[-66.766001,18.482727]]]}}, -{"type":"Feature","id":"72067","properties":{"name":"Hormigueros"},"geometry":{"type":"Polygon","coordinates":[[[-67.116525,18.159588],[-67.083663,18.148634],[-67.100094,18.104819],[-67.16034,18.154111],[-67.116525,18.159588]]]}}, -{"type":"Feature","id":"72069","properties":{"name":"Humacao"},"geometry":{"type":"Polygon","coordinates":[[[-65.823967,18.197926],[-65.741813,18.176019],[-65.796582,18.071957],[-65.878736,18.115772],[-65.823967,18.197926]]]}}, -{"type":"Feature","id":"72071","properties":{"name":"Isabela"},"geometry":{"type":"Polygon","coordinates":[[[-67.105571,18.515589],[-67.105571,18.515589],[-66.957694,18.488204],[-66.919355,18.395096],[-67.012463,18.395096],[-67.028894,18.395096],[-67.056278,18.46082],[-67.105571,18.515589]]]}}, -{"type":"Feature","id":"72073","properties":{"name":"Jayuya"},"geometry":{"type":"Polygon","coordinates":[[[-66.568831,18.296511],[-66.541446,18.165065],[-66.546923,18.154111],[-66.5524,18.154111],[-66.650985,18.159588],[-66.568831,18.296511]]]}}, -{"type":"Feature","id":"72075","properties":{"name":"Juana Díaz"},"geometry":{"type":"Polygon","coordinates":[[[-66.546923,18.154111],[-66.519538,18.154111],[-66.431907,18.082911],[-66.42643,18.044572],[-66.448338,17.984326],[-66.535969,17.978849],[-66.5524,18.154111],[-66.546923,18.154111]]]}}, -{"type":"Feature","id":"72077","properties":{"name":"Juncos"},"geometry":{"type":"Polygon","coordinates":[[[-65.917075,18.269127],[-65.851352,18.252696],[-65.928029,18.143157],[-65.949936,18.230788],[-65.917075,18.269127]]]}}, -{"type":"Feature","id":"72079","properties":{"name":"Lajas"},"geometry":{"type":"Polygon","coordinates":[[[-67.067232,18.06648],[-66.985078,18.050049],[-66.957694,18.033618],[-66.979601,17.951464],[-67.111048,17.945987],[-67.111048,18.055526],[-67.067232,18.06648]]]}}, -{"type":"Feature","id":"72081","properties":{"name":"Lares"},"geometry":{"type":"Polygon","coordinates":[[[-66.89197,18.367712],[-66.826247,18.340327],[-66.826247,18.323896],[-66.815293,18.230788],[-66.826247,18.170542],[-66.837201,18.170542],[-66.897447,18.186973],[-66.908401,18.252696],[-66.89197,18.367712]]]}}, -{"type":"Feature","id":"72083","properties":{"name":"Las Marías"},"geometry":{"type":"Polygon","coordinates":[[[-67.039848,18.291034],[-66.908401,18.252696],[-66.897447,18.186973],[-66.913878,18.19245],[-67.01794,18.197926],[-67.083663,18.252696],[-67.039848,18.291034]]]}}, -{"type":"Feature","id":"72085","properties":{"name":"Las Piedras"},"geometry":{"type":"Polygon","coordinates":[[[-65.823967,18.274604],[-65.823967,18.197926],[-65.878736,18.115772],[-65.906121,18.126726],[-65.928029,18.121249],[-65.928029,18.143157],[-65.851352,18.252696],[-65.834921,18.274604],[-65.823967,18.274604]]]}}, -{"type":"Feature","id":"72087","properties":{"name":"Loíza"},"geometry":{"type":"Polygon","coordinates":[[[-65.829444,18.422481],[-65.867782,18.378666],[-65.911598,18.400573],[-65.917075,18.400573],[-65.993752,18.46082],[-65.829444,18.422481]]]}}, -{"type":"Feature","id":"72089","properties":{"name":"Luquillo"},"geometry":{"type":"Polygon","coordinates":[[[-65.758244,18.291034],[-65.752767,18.384142],[-65.670613,18.362235],[-65.752767,18.296511],[-65.758244,18.291034]]]}}, -{"type":"Feature","id":"72091","properties":{"name":"Manatí"},"geometry":{"type":"Polygon","coordinates":[[[-66.437384,18.482727],[-66.442861,18.373189],[-66.464769,18.373189],[-66.475723,18.367712],[-66.535969,18.351281],[-66.541446,18.400573],[-66.541446,18.40605],[-66.535969,18.482727],[-66.437384,18.488204],[-66.437384,18.482727]]]}}, -{"type":"Feature","id":"72093","properties":{"name":"Maricao"},"geometry":{"type":"Polygon","coordinates":[[[-66.913878,18.19245],[-66.897447,18.186973],[-66.837201,18.170542],[-66.924832,18.148634],[-66.979601,18.143157],[-67.050802,18.176019],[-67.01794,18.197926],[-66.913878,18.19245]]]}}, -{"type":"Feature","id":"72095","properties":{"name":"Maunabo"},"geometry":{"type":"Polygon","coordinates":[[[-65.988275,18.061003],[-65.851352,18.011711],[-65.911598,17.984326],[-65.988275,18.061003]]]}}, -{"type":"Feature","id":"72097","properties":{"name":"Mayagüez"},"geometry":{"type":"Polygon","coordinates":[[[-67.16034,18.274604],[-67.083663,18.252696],[-67.01794,18.197926],[-67.050802,18.176019],[-67.083663,18.148634],[-67.116525,18.159588],[-67.16034,18.154111],[-67.182248,18.170542],[-67.187725,18.269127],[-67.16034,18.274604]]]}}, -{"type":"Feature","id":"72099","properties":{"name":"Moca"},"geometry":{"type":"Polygon","coordinates":[[[-67.056278,18.46082],[-67.028894,18.395096],[-67.050802,18.307465],[-67.122002,18.323896],[-67.127479,18.318419],[-67.132956,18.389619],[-67.056278,18.46082]]]}}, -{"type":"Feature","id":"72101","properties":{"name":"Morovis"},"geometry":{"type":"Polygon","coordinates":[[[-66.442861,18.373189],[-66.377138,18.345804],[-66.366184,18.33485],[-66.377138,18.296511],[-66.453815,18.258173],[-66.464769,18.373189],[-66.442861,18.373189]]]}}, -{"type":"Feature","id":"72103","properties":{"name":"Naguabo"},"geometry":{"type":"Polygon","coordinates":[[[-65.823967,18.274604],[-65.769197,18.280081],[-65.659659,18.20888],[-65.741813,18.176019],[-65.823967,18.197926],[-65.823967,18.274604]]]}}, -{"type":"Feature","id":"72105","properties":{"name":"Naranjito"},"geometry":{"type":"Polygon","coordinates":[[[-66.256645,18.329373],[-66.207353,18.318419],[-66.207353,18.274604],[-66.267599,18.247219],[-66.311415,18.247219],[-66.278553,18.329373],[-66.256645,18.329373]]]}}, -{"type":"Feature","id":"72107","properties":{"name":"Orocovis"},"geometry":{"type":"Polygon","coordinates":[[[-66.377138,18.296511],[-66.349753,18.241742],[-66.371661,18.176019],[-66.442861,18.176019],[-66.453815,18.176019],[-66.519538,18.154111],[-66.546923,18.154111],[-66.541446,18.165065],[-66.453815,18.258173],[-66.377138,18.296511]]]}}, -{"type":"Feature","id":"72109","properties":{"name":"Patillas"},"geometry":{"type":"Polygon","coordinates":[[[-66.053998,18.104819],[-66.053998,18.110295],[-66.010183,18.077434],[-65.988275,18.061003],[-65.911598,17.984326],[-66.021137,17.978849],[-66.059475,18.039095],[-66.081383,18.033618],[-66.053998,18.104819]]]}}, -{"type":"Feature","id":"72111","properties":{"name":"Peñuelas"},"geometry":{"type":"Polygon","coordinates":[[[-66.716708,18.132203],[-66.6948,18.132203],[-66.700277,17.978849],[-66.755047,18.000757],[-66.771478,18.13768],[-66.716708,18.132203]]]}}, -{"type":"Feature","id":"72113","properties":{"name":"Ponce"},"geometry":{"type":"Polygon","coordinates":[[[-66.650985,18.159588],[-66.5524,18.154111],[-66.535969,17.978849],[-66.700277,17.978849],[-66.6948,18.132203],[-66.672893,18.154111],[-66.650985,18.159588]]]}}, -{"type":"Feature","id":"72115","properties":{"name":"Quebradillas"},"geometry":{"type":"Polygon","coordinates":[[[-66.902924,18.482727],[-66.897447,18.367712],[-66.919355,18.395096],[-66.957694,18.488204],[-66.902924,18.482727]]]}}, -{"type":"Feature","id":"72117","properties":{"name":"Rincón"},"geometry":{"type":"Polygon","coordinates":[[[-67.237017,18.373189],[-67.182248,18.312942],[-67.226064,18.296511],[-67.237017,18.373189]]]}}, -{"type":"Feature","id":"72119","properties":{"name":"Río Grande"},"geometry":{"type":"Polygon","coordinates":[[[-65.752767,18.384142],[-65.758244,18.291034],[-65.769197,18.280081],[-65.823967,18.274604],[-65.834921,18.274604],[-65.867782,18.378666],[-65.829444,18.422481],[-65.752767,18.384142]]]}}, -{"type":"Feature","id":"72121","properties":{"name":"Sabana Grande"},"geometry":{"type":"Polygon","coordinates":[[[-66.924832,18.148634],[-66.886493,18.022664],[-66.957694,18.033618],[-66.985078,18.050049],[-66.979601,18.143157],[-66.924832,18.148634]]]}}, -{"type":"Feature","id":"72123","properties":{"name":"Salinas"},"geometry":{"type":"Polygon","coordinates":[[[-66.223784,18.093865],[-66.163537,18.050049],[-66.207353,17.962418],[-66.338799,17.978849],[-66.333322,18.017187],[-66.256645,18.077434],[-66.223784,18.093865]]]}}, -{"type":"Feature","id":"72125","properties":{"name":"San Germán"},"geometry":{"type":"Polygon","coordinates":[[[-67.050802,18.176019],[-66.979601,18.143157],[-66.985078,18.050049],[-67.067232,18.06648],[-67.111048,18.055526],[-67.100094,18.104819],[-67.083663,18.148634],[-67.050802,18.176019]]]}}, -{"type":"Feature","id":"72127","properties":{"name":"San Juan"},"geometry":{"type":"Polygon","coordinates":[[[-66.037568,18.449866],[-65.999229,18.378666],[-66.043044,18.312942],[-66.064952,18.301988],[-66.081383,18.296511],[-66.108768,18.438912],[-66.125199,18.46082],[-66.037568,18.449866]]]}}, -{"type":"Feature","id":"72129","properties":{"name":"San Lorenzo"},"geometry":{"type":"Polygon","coordinates":[[[-65.966367,18.230788],[-65.949936,18.230788],[-65.928029,18.143157],[-65.928029,18.121249],[-66.010183,18.077434],[-66.053998,18.110295],[-66.053998,18.115772],[-65.999229,18.20888],[-65.966367,18.230788]]]}}, -{"type":"Feature","id":"72131","properties":{"name":"San Sebastián"},"geometry":{"type":"Polygon","coordinates":[[[-67.012463,18.395096],[-66.919355,18.395096],[-66.897447,18.367712],[-66.89197,18.367712],[-66.908401,18.252696],[-67.039848,18.291034],[-67.050802,18.307465],[-67.028894,18.395096],[-67.012463,18.395096]]]}}, -{"type":"Feature","id":"72133","properties":{"name":"Santa Isabel"},"geometry":{"type":"Polygon","coordinates":[[[-66.382615,18.039095],[-66.333322,18.017187],[-66.338799,17.978849],[-66.448338,17.984326],[-66.42643,18.044572],[-66.382615,18.039095]]]}}, -{"type":"Feature","id":"72135","properties":{"name":"Toa Alta"},"geometry":{"type":"Polygon","coordinates":[[[-66.218307,18.395096],[-66.196399,18.389619],[-66.207353,18.318419],[-66.256645,18.329373],[-66.278553,18.329373],[-66.305938,18.367712],[-66.316892,18.367712],[-66.305938,18.384142],[-66.251168,18.395096],[-66.218307,18.395096]]]}}, -{"type":"Feature","id":"72137","properties":{"name":"Toa Baja"},"geometry":{"type":"Polygon","coordinates":[[[-66.141629,18.46082],[-66.169014,18.433435],[-66.196399,18.389619],[-66.218307,18.395096],[-66.251168,18.395096],[-66.196399,18.466297],[-66.141629,18.46082]]]}}, -{"type":"Feature","id":"72139","properties":{"name":"Trujillo Alto"},"geometry":{"type":"Polygon","coordinates":[[[-65.999229,18.378666],[-65.94446,18.291034],[-65.982798,18.312942],[-66.021137,18.307465],[-66.043044,18.312942],[-65.999229,18.378666]]]}}, -{"type":"Feature","id":"72141","properties":{"name":"Utuado"},"geometry":{"type":"Polygon","coordinates":[[[-66.711231,18.312942],[-66.607169,18.329373],[-66.568831,18.296511],[-66.650985,18.159588],[-66.672893,18.154111],[-66.722185,18.219834],[-66.815293,18.230788],[-66.826247,18.323896],[-66.771478,18.323896],[-66.711231,18.312942]]]}}, -{"type":"Feature","id":"72143","properties":{"name":"Vega Alta"},"geometry":{"type":"Polygon","coordinates":[[[-66.316892,18.47725],[-66.305938,18.384142],[-66.316892,18.367712],[-66.366184,18.33485],[-66.377138,18.345804],[-66.349753,18.488204],[-66.316892,18.47725]]]}}, -{"type":"Feature","id":"72145","properties":{"name":"Vega Baja"},"geometry":{"type":"Polygon","coordinates":[[[-66.349753,18.488204],[-66.377138,18.345804],[-66.442861,18.373189],[-66.437384,18.482727],[-66.437384,18.488204],[-66.349753,18.488204]]]}}, -{"type":"Feature","id":"72149","properties":{"name":"Villalba"},"geometry":{"type":"Polygon","coordinates":[[[-66.453815,18.176019],[-66.442861,18.176019],[-66.431907,18.082911],[-66.519538,18.154111],[-66.453815,18.176019]]]}}, -{"type":"Feature","id":"72151","properties":{"name":"Yabucoa"},"geometry":{"type":"Polygon","coordinates":[[[-65.906121,18.126726],[-65.878736,18.115772],[-65.796582,18.071957],[-65.851352,18.011711],[-65.988275,18.061003],[-66.010183,18.077434],[-65.928029,18.121249],[-65.906121,18.126726]]]}}, -{"type":"Feature","id":"72153","properties":{"name":"Yauco"},"geometry":{"type":"Polygon","coordinates":[[[-66.826247,18.170542],[-66.798862,18.132203],[-66.853632,17.956941],[-66.859109,17.956941],[-66.886493,18.022664],[-66.924832,18.148634],[-66.837201,18.170542],[-66.826247,18.170542]]]}} -]} diff --git a/test/dsv/csv-test.js b/test/dsv/csv-test.js deleted file mode 100644 index 9273e2ccab8749..00000000000000 --- a/test/dsv/csv-test.js +++ /dev/null @@ -1,214 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.csv"); - -suite.addBatch({ - "csv": { - topic: load("dsv/csv").expression("d3.csv").document(), - - "on a sample file": { - topic: function(csv) { - csv("test/data/sample.csv", this.callback); - }, - "invokes the callback with the parsed CSV": function(csv) { - assert.deepEqual(csv, [{"Hello":"42","World":"\"fish\""}]); - }, - "overrides the mime type to text/csv": function(csv) { - assert.equal(XMLHttpRequest._last._info.mimeType, "text/csv"); - } - }, - - "when specifying a row conversion function": { - topic: function(csv) { - csv("test/data/sample.csv", function(row) { - row.Hello = -row.Hello; - return row; - }, this.callback); - }, - "invokes the callback with the parsed CSV": function(csv) { - assert.strictEqual(csv[0].Hello, -42); - } - }, - - "when loading a file that does not exist": { - topic: function(csv) { - var callback = this.callback; - csv("//does/not/exist.csv", function(error, csv) { - callback(null, csv); - }); - }, - "invokes the callback with undefined": function(csv) { - assert.isUndefined(csv); - } - }, - - "parse": { - topic: function(csv) { - return csv.parse; - }, - "returns an array of objects": function(parse) { - assert.deepEqual(parse("a,b,c\n1,2,3\n"), [{a: "1", b: "2", c: "3"}]); - }, - "does not strip whitespace": function(parse) { - assert.deepEqual(parse("a,b,c\n 1, 2,3\n"), [{a: " 1", b: " 2", c: "3"}]); - }, - "parses quoted values": function(parse) { - assert.deepEqual(parse("a,b,c\n\"1\",2,3"), [{a: "1", b: "2", c: "3"}]); - assert.deepEqual(parse("a,b,c\n\"1\",2,3\n"), [{a: "1", b: "2", c: "3"}]); - }, - "parses quoted values with quotes": function(parse) { - assert.deepEqual(parse("a\n\"\"\"hello\"\"\""), [{a: "\"hello\""}]); - }, - "parses quoted values with newlines": function(parse) { - assert.deepEqual(parse("a\n\"new\nline\""), [{a: "new\nline"}]); - assert.deepEqual(parse("a\n\"new\rline\""), [{a: "new\rline"}]); - assert.deepEqual(parse("a\n\"new\r\nline\""), [{a: "new\r\nline"}]); - }, - "parses unix newlines": function(parse) { - assert.deepEqual(parse("a,b,c\n1,2,3\n4,5,\"6\"\n7,8,9"), [ - {a: "1", b: "2", c: "3"}, - {a: "4", b: "5", c: "6"}, - {a: "7", b: "8", c: "9"} - ]); - }, - "parses mac newlines": function(parse) { - assert.deepEqual(parse("a,b,c\r1,2,3\r4,5,\"6\"\r7,8,9"), [ - {a: "1", b: "2", c: "3"}, - {a: "4", b: "5", c: "6"}, - {a: "7", b: "8", c: "9"} - ]); - }, - "parses dos newlines": function(parse) { - assert.deepEqual(parse("a,b,c\r\n1,2,3\r\n4,5,\"6\"\r\n7,8,9"), [ - {a: "1", b: "2", c: "3"}, - {a: "4", b: "5", c: "6"}, - {a: "7", b: "8", c: "9"} - ]); - } - }, - - "parse with row function": { - "invokes the row function for every row in order": function(csv) { - var rows = []; - csv.parse("a\n1\n2\n3\n4", function(d, i) { rows.push({d: d, i: i}); }); - assert.deepEqual(rows, [ - {d: {a: "1"}, i: 0}, - {d: {a: "2"}, i: 1}, - {d: {a: "3"}, i: 2}, - {d: {a: "4"}, i: 3} - ]); - }, - "returns an array of the row function return values": function(csv) { - assert.deepEqual(csv.parse("a,b,c\n1,2,3\n", function(row) { return row; }), [{a: "1", b: "2", c: "3"}]); - }, - "skips rows if the row function returns null or undefined": function(csv) { - assert.deepEqual(csv.parse("a,b,c\n1,2,3\n2,3,4", function(row) { return row.a & 1 ? null : row; }), [{a: "2", b: "3", c: "4"}]); - assert.deepEqual(csv.parse("a,b,c\n1,2,3\n2,3,4", function(row) { return row.a & 1 ? undefined : row; }), [{a: "2", b: "3", c: "4"}]); - } - }, - - "parseRows": { - topic: function(csv) { - return csv.parseRows; - }, - "returns an array of arrays": function(parse) { - assert.deepEqual(parse("a,b,c\n"), [["a", "b", "c"]]); - }, - "parses quoted values": function(parse) { - assert.deepEqual(parse("\"1\",2,3\n"), [["1", "2", "3"]]); - assert.deepEqual(parse("\"hello\""), [["hello"]]); - }, - "parses quoted values with quotes": function(parse) { - assert.deepEqual(parse("\"\"\"hello\"\"\""), [["\"hello\""]]); - }, - "parses quoted values with newlines": function(parse) { - assert.deepEqual(parse("\"new\nline\""), [["new\nline"]]); - assert.deepEqual(parse("\"new\rline\""), [["new\rline"]]); - assert.deepEqual(parse("\"new\r\nline\""), [["new\r\nline"]]); - }, - "parses unix newlines": function(parse) { - assert.deepEqual(parse("a,b,c\n1,2,3\n4,5,\"6\"\n7,8,9"), [ - ["a", "b", "c"], - ["1", "2", "3"], - ["4", "5", "6"], - ["7", "8", "9"] - ]); - }, - "parses mac newlines": function(parse) { - assert.deepEqual(parse("a,b,c\r1,2,3\r4,5,\"6\"\r7,8,9"), [ - ["a", "b", "c"], - ["1", "2", "3"], - ["4", "5", "6"], - ["7", "8", "9"] - ]); - }, - "parses dos newlines": function(parse) { - assert.deepEqual(parse("a,b,c\r\n1,2,3\r\n4,5,\"6\"\r\n7,8,9"), [ - ["a", "b", "c"], - ["1", "2", "3"], - ["4", "5", "6"], - ["7", "8", "9"] - ]); - } - }, - - "format": { - topic: function(csv) { - return csv.format; - }, - "takes an array of objects as input": function(format) { - assert.equal(format([{a: 1, b: 2, c: 3}]), "a,b,c\n1,2,3"); - }, - "escapes field names containing special characters": function(format) { - assert.equal(format([{"foo,bar": true}]), "\"foo,bar\"\ntrue"); - }, - "computes the union of all fields": function(format) { - assert.equal(format([ - {a: 1}, - {a: 1, b: 2}, - {a: 1, b: 2, c: 3}, - {b: 1, c: 2}, - {c: 1} - ]), "a,b,c\n1,,\n1,2,\n1,2,3\n,1,2\n,,1"); - }, - "orders field by first-seen": function(format) { - assert.equal(format([ - {a: 1, b: 2}, - {c: 3, b: 4}, - {c: 5, a: 1, b: 2} - ]), "a,b,c\n1,2,\n,4,3\n1,2,5"); - } - }, - - "formatRows": { - topic: function(csv) { - return csv.formatRows; - }, - "takes an array of arrays as input": function(format) { - assert.equal(format([["a", "b", "c"], ["1", "2", "3"]]), "a,b,c\n1,2,3"); - }, - "separates lines using unix newline": function(format) { - assert.equal(format([[], []]), "\n"); - }, - "does not strip whitespace": function(format) { - assert.equal(format([["a ", " b", "c"], ["1", "2", "3 "]]), "a , b,c\n1,2,3 "); - }, - "does not quote simple values": function(format) { - assert.equal(format([["a"], [1]]), "a\n1"); - }, - "escapes double quotes": function(format) { - assert.equal(format([["\"fish\""]]), "\"\"\"fish\"\"\""); - }, - "escapes unix newlines": function(format) { - assert.equal(format([["new\nline"]]), "\"new\nline\""); - }, - "escapes commas": function(format) { - assert.equal(format([["oxford,comma"]]), "\"oxford,comma\""); - } - } - } -}); - -suite.export(module); diff --git a/test/dsv/tsv-test.js b/test/dsv/tsv-test.js deleted file mode 100644 index 016c0a57393b41..00000000000000 --- a/test/dsv/tsv-test.js +++ /dev/null @@ -1,185 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.tsv"); - -suite.addBatch({ - "tsv": { - topic: load("dsv/tsv").expression("d3.tsv").document(), - - "on a sample file": { - topic: function(tsv) { - tsv("test/data/sample.tsv", this.callback); - }, - "invokes the callback with the parsed tsv": function(tsv) { - assert.deepEqual(tsv, [{"Hello":42,"World":"\"fish\""}]); - }, - "overrides the mime type to text/tab-separated-values": function(tsv) { - assert.equal(XMLHttpRequest._last._info.mimeType, "text/tab-separated-values"); - } - }, - - "on a file that does not exist": { - topic: function(tsv) { - var callback = this.callback; - tsv("//does/not/exist.tsv", function(error, tsv) { - callback(null, tsv); - }); - }, - "invokes the callback with undefined when an error occurs": function(tsv) { - assert.isUndefined(tsv); - } - }, - - "parse": { - topic: function(tsv) { - return tsv.parse; - }, - "returns an array of objects": function(parse) { - assert.deepEqual(parse("a\tb\tc\n1\t2\t3\n"), [{a: "1", b: "2", c: "3"}]); - }, - "does not strip whitespace": function(parse) { - assert.deepEqual(parse("a\tb\tc\n 1\t 2\t3\n"), [{a: " 1", b: " 2", c: "3"}]); - }, - "parses quoted values": function(parse) { - assert.deepEqual(parse("a\tb\tc\n\"1\"\t2\t3"), [{a: "1", b: "2", c: "3"}]); - assert.deepEqual(parse("a\tb\tc\n\"1\"\t2\t3\n"), [{a: "1", b: "2", c: "3"}]); - }, - "parses quoted values with quotes": function(parse) { - assert.deepEqual(parse("a\n\"\"\"hello\"\"\""), [{a: "\"hello\""}]); - }, - "parses quoted values with newlines": function(parse) { - assert.deepEqual(parse("a\n\"new\nline\""), [{a: "new\nline"}]); - assert.deepEqual(parse("a\n\"new\rline\""), [{a: "new\rline"}]); - assert.deepEqual(parse("a\n\"new\r\nline\""), [{a: "new\r\nline"}]); - }, - "parses unix newlines": function(parse) { - assert.deepEqual(parse("a\tb\tc\n1\t2\t3\n4\t5\t\"6\"\n7\t8\t9"), [ - {a: "1", b: "2", c: "3"}, - {a: "4", b: "5", c: "6"}, - {a: "7", b: "8", c: "9"} - ]); - }, - "parses mac newlines": function(parse) { - assert.deepEqual(parse("a\tb\tc\r1\t2\t3\r4\t5\t\"6\"\r7\t8\t9"), [ - {a: "1", b: "2", c: "3"}, - {a: "4", b: "5", c: "6"}, - {a: "7", b: "8", c: "9"} - ]); - }, - "parses dos newlines": function(parse) { - assert.deepEqual(parse("a\tb\tc\r\n1\t2\t3\r\n4\t5\t\"6\"\r\n7\t8\t9"), [ - {a: "1", b: "2", c: "3"}, - {a: "4", b: "5", c: "6"}, - {a: "7", b: "8", c: "9"} - ]); - } - }, - - "parseRows": { - topic: function(tsv) { - return tsv.parseRows; - }, - "returns an array of arrays": function(parse) { - assert.deepEqual(parse("a\tb\tc\n"), [["a", "b", "c"]]); - }, - "parses quoted values": function(parse) { - assert.deepEqual(parse("\"1\"\t2\t3\n"), [["1", "2", "3"]]); - assert.deepEqual(parse("\"hello\""), [["hello"]]); - }, - "parses quoted values with quotes": function(parse) { - assert.deepEqual(parse("\"\"\"hello\"\"\""), [["\"hello\""]]); - }, - "parses quoted values with newlines": function(parse) { - assert.deepEqual(parse("\"new\nline\""), [["new\nline"]]); - assert.deepEqual(parse("\"new\rline\""), [["new\rline"]]); - assert.deepEqual(parse("\"new\r\nline\""), [["new\r\nline"]]); - }, - "parses unix newlines": function(parse) { - assert.deepEqual(parse("a\tb\tc\n1\t2\t3\n4\t5\t\"6\"\n7\t8\t9"), [ - ["a", "b", "c"], - ["1", "2", "3"], - ["4", "5", "6"], - ["7", "8", "9"] - ]); - }, - "parses mac newlines": function(parse) { - assert.deepEqual(parse("a\tb\tc\r1\t2\t3\r4\t5\t\"6\"\r7\t8\t9"), [ - ["a", "b", "c"], - ["1", "2", "3"], - ["4", "5", "6"], - ["7", "8", "9"] - ]); - }, - "parses dos newlines": function(parse) { - assert.deepEqual(parse("a\tb\tc\r\n1\t2\t3\r\n4\t5\t\"6\"\r\n7\t8\t9"), [ - ["a", "b", "c"], - ["1", "2", "3"], - ["4", "5", "6"], - ["7", "8", "9"] - ]); - } - }, - - "format": { - topic: function(tsv) { - return tsv.format; - }, - "takes an array of objects as input": function(format) { - assert.equal(format([{a: 1, b: 2, c: 3}]), "a\tb\tc\n1\t2\t3"); - }, - "escapes field names containing special characters": function(format) { - assert.equal(format([{"foo\tbar": true}]), "\"foo\tbar\"\ntrue"); - }, - "computes the union of all fields": function(format) { - assert.equal(format([ - {a: 1}, - {a: 1, b: 2}, - {a: 1, b: 2, c: 3}, - {b: 1, c: 2}, - {c: 1} - ]), "a\tb\tc\n1\t\t\n1\t2\t\n1\t2\t3\n\t1\t2\n\t\t1"); - }, - "orders field by first-seen": function(format) { - assert.equal(format([ - {a: 1, b: 2}, - {c: 3, b: 4}, - {c: 5, a: 1, b: 2} - ]), "a\tb\tc\n1\t2\t\n\t4\t3\n1\t2\t5"); - } - }, - - "formatRows": { - topic: function(tsv) { - return tsv.formatRows; - }, - "takes an array of arrays as input": function(format) { - assert.equal(format([["a", "b", "c"], ["1", "2", "3"]]), "a\tb\tc\n1\t2\t3"); - }, - "separates lines using unix newline": function(format) { - assert.equal(format([[], []]), "\n"); - }, - "does not strip whitespace": function(format) { - assert.equal(format([["a ", " b", "c"], ["1", "2", "3 "]]), "a \t b\tc\n1\t2\t3 "); - }, - "does not quote simple values": function(format) { - assert.equal(format([["a"], [1]]), "a\n1"); - }, - "escapes double quotes": function(format) { - assert.equal(format([["\"fish\""]]), "\"\"\"fish\"\"\""); - }, - "escapes unix newlines": function(format) { - assert.equal(format([["new\nline"]]), "\"new\nline\""); - }, - "escapes tabs": function(format) { - assert.equal(format([["oxford\tcomma"]]), "\"oxford\tcomma\""); - }, - "does not escape commas": function(format) { - assert.equal(format([["oxford,comma"]]), "oxford,comma"); - } - } - } -}); - -suite.export(module); diff --git a/test/event/dispatch-test.js b/test/event/dispatch-test.js deleted file mode 100644 index d365fd4f25bfcd..00000000000000 --- a/test/event/dispatch-test.js +++ /dev/null @@ -1,163 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.dispatch"); - -suite.addBatch({ - "dispatch": { - topic: load("event/dispatch").expression("d3.dispatch"), - "returns a map of dispatchers for each event type": function(dispatch) { - assert.deepEqual(dispatch(), {}); - var d = dispatch("foo"); - assert.isTrue("foo" in d); - assert.isFalse("bar" in d); - var d = dispatch("foo", "bar"); - assert.isTrue("foo" in d); - assert.isTrue("bar" in d); - }, - "added listeners receive subsequent events": function(dispatch) { - var d = dispatch("foo"), events = 0; - d.on("foo", function() { ++events; }); - d.foo(); - assert.equal(events, 1); - d.foo(); - d.foo(); - assert.equal(events, 3); - }, - "the listener is passed any arguments to dispatch": function(dispatch) { - var d = dispatch("foo"), a = {}, b = {}, aa, bb; - d.on("foo", function(a, b) { aa = a; bb = b; }); - d.foo(a, b); - assert.equal(aa, a); - assert.equal(bb, b); - d.foo(1, "foo"); - assert.equal(aa, 1); - assert.equal(bb, "foo"); - }, - "the listener's context is the same as dispatch's": function(dispatch) { - var d = dispatch("foo"), a = {}, b = {}, that; - d.on("foo", function() { that = this; }); - d.foo.call(a); - assert.equal(that, a); - d.foo.call(b); - assert.equal(that, b); - }, - "listeners are notified in the order they are added": function(dispatch) { - var d = dispatch("foo"), a = {}, b = {}, those = []; - function A() { those.push(a); } - function B() { those.push(b); } - d.on("foo.a", A).on("foo.b", B); - d.foo(); - assert.deepEqual(those, [a, b]); - those = []; - d.on("foo.a", A); // move to the end - d.foo(); - assert.deepEqual(those, [b, a]); - }, - "notifying listeners returns the dispatch object": function(dispatch) { - var d = dispatch("foo"); - assert.equal(d.foo(), d); - }, - "adding a listener returns the dispatch object": function(dispatch) { - var d = dispatch("foo"); - function A() {} - assert.equal(d.on("foo", A), d); - }, - "removed listeners do not receive subsequent events": function(dispatch) { - var d = dispatch("foo"), a = {}, b = {}, those = []; - function A() { those.push(a); } - function B() { those.push(b); } - d.on("foo.a", A).on("foo.b", B); - d.foo(); - those = []; - d.on("foo.a", null); - d.foo(); - assert.deepEqual(those, [b]); - }, - "removing a shared listener only affects the intended event": function(dispatch) { - var d = dispatch("foo", "bar"), a = 0; - function A() { ++a; } - d.on("foo", A).on("bar", A); - d.foo(); - d.bar(); - assert.equal(a, 2); - d.on("foo", null); - d.bar(); - assert.equal(a, 3); - }, - "adding an existing listener has no effect": function(dispatch) { - var d = dispatch("foo"), events = 0; - function A() { ++events; } - d.on("foo.a", A); - d.foo(); - d.on("foo.a", A).on("foo.a", A); - d.foo(); - assert.equal(events, 2); - }, - "removing a missing listener has no effect": function(dispatch) { - var d = dispatch("foo"), events = 0; - function A() { ++events; } - d.on("foo.a", null).on("foo", A).on("foo", null).on("foo", null); - d.foo(); - assert.equal(events, 0); - }, - "adding a listener does not affect the current event": function(dispatch) { - var d = dispatch("foo"), a = {}, b = {}, those = []; - function A() { d.on("foo.b", B); those.push(a); } - function B() { those.push(b); } - d.on("foo.a", A); - d.foo(); - assert.deepEqual(those, [a]); - }, - "removing a listener does affect the current event": function(dispatch) { - var d = dispatch("foo"), a = {}, b = {}, those = []; - function A() { d.on("foo.b", null); those.push(a); } - function B() { those.push(b); } - d.on("foo.a", A).on("foo.b", B); - d.foo(); - assert.deepEqual(those, [a]); - }, - "getting a listener returns the correct listener": function(dispatch) { - var d = dispatch("foo"); - function A() {} - function B() {} - function C() {} - d.on("foo.a", A).on("foo.b", B).on("foo", C); - assert.equal(d.on("foo.a"), A); - assert.equal(d.on("foo.b"), B); - assert.equal(d.on("foo"), C); - }, - "omitting the event type": { - "returns undefined when retrieving a listener": function(dispatch) { - var d = dispatch("foo"); - assert.isUndefined(d.on(".a")); - }, - "null removes all named event listeners": function(dispatch) { - var d = dispatch("foo", "bar"), a = {}, b = {}, c = {}, those = []; - function A() { those.push(a); } - function B() { those.push(b); } - function C() { those.push(c); } - d.on("foo.a", A).on("bar.a", B).on("foo", C).on(".a", null); - d.foo(); - d.bar(); - assert.deepEqual(those, [c]); - }, - "no-op when setting a listener": function(dispatch) { - var d = dispatch("foo", "bar"), a = {}, b = {}, those = []; - function A() { those.push(a); } - function B() { those.push(b); } - d - .on(".a", A) - .on("foo.a", B) - .on("bar", B); - d.foo(); - d.bar(); - assert.deepEqual(those, [b, b]); - assert.isUndefined(d.on(".a")); - } - } - } -}); - -suite.export(module); diff --git a/test/event/mouse-test.html b/test/event/mouse-test.html deleted file mode 100644 index 219f8eca29fc35..00000000000000 --- a/test/event/mouse-test.html +++ /dev/null @@ -1,22 +0,0 @@ - - -HTML Mouse Test - - - diff --git a/test/event/timer-test.js b/test/event/timer-test.js deleted file mode 100644 index f86039ce580d16..00000000000000 --- a/test/event/timer-test.js +++ /dev/null @@ -1,74 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.timer"); - -suite.addBatch({ - "timer": { - topic: load("event/timer").expression("d3.timer").document(), - - "with no delay": { - topic: delay(), - "first calls after 17 ms or less": function(info) { - assert.inDelta(info.start - info.scheduled, 17, 20); - }, - "calls until the function returns true": function(info) { - assert.equal(info.count, 4); - }, - "calls every 17 ms": function(info) { - assert.inDelta(info.stop - info.start, 17 * 3, 20); - } - }, - - "with a specified delay": { - topic: delay(250), - "first calls after the delay": function(info) { - assert.inDelta(info.start - info.scheduled, 250, 20); - }, - "calls until the function returns true": function(info) { - assert.equal(info.count, 4); - }, - "calls every 17 ms": function(info) { - assert.inDelta(info.stop - info.start, 17 * 3, 20); - } - }, - - "with multiple registered tasks": { - topic: function(timer) { - var callback = this.callback, - results = []; - timer(function() { results.push("A"); return true; }); - timer(function() { results.push("B"); return true; }); - timer(function() { results.push("C"); return true; }); - timer(function() { callback(null, results); return true; }) - }, - "invokes tasks in the order they were registered": function(results) { - assert.deepEqual(results, ["A", "B", "C"]); - } - } - } -}); - -function delay(delay) { - var args = Array.prototype.slice.call(arguments); - return function(timer) { - var cb = this.callback, - info = {scheduled: Date.now(), count: 0}; - - args.unshift(function() { - var count = ++info.count; - if (count === 1) { - info.start = Date.now(); - } else if (count === 4) { - info.stop = Date.now(); - cb(null, info); - return true; - } - }); - - timer.apply(this, args); - }; -} - -suite.export(module); diff --git a/test/event/touch-test.html b/test/event/touch-test.html deleted file mode 100644 index 94f14518b08685..00000000000000 --- a/test/event/touch-test.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - diff --git a/test/format/format-test.js b/test/format/format-test.js deleted file mode 100644 index 4da985b03362e1..00000000000000 --- a/test/format/format-test.js +++ /dev/null @@ -1,360 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.format"); - -suite.addBatch({ - "format": { - topic: load("format/format").expression("d3.format"), - "returns a string": function(format) { - assert.isString(format("d")(0)); - }, - "can zero fill": function(format) { - var f = format("08d"); - assert.strictEqual(f(0), "00000000"); - assert.strictEqual(f(42), "00000042"); - assert.strictEqual(f(42000000), "42000000"); - assert.strictEqual(f(420000000), "420000000"); - assert.strictEqual(f(-4), "-0000004"); - assert.strictEqual(f(-42), "-0000042"); - assert.strictEqual(f(-4200000), "-4200000"); - assert.strictEqual(f(-42000000), "-42000000"); - }, - "can space fill": function(format) { - var f = format("8d"); - assert.strictEqual(f(0), " 0"); - assert.strictEqual(f(42), " 42"); - assert.strictEqual(f(42000000), "42000000"); - assert.strictEqual(f(420000000), "420000000"); - assert.strictEqual(f(-4), " -4"); - assert.strictEqual(f(-42), " -42"); - assert.strictEqual(f(-4200000), "-4200000"); - assert.strictEqual(f(-42000000), "-42000000"); - }, - "can output fixed-point notation": function(format) { - assert.strictEqual(format(".1f")(0.49), "0.5"); - assert.strictEqual(format(".2f")(0.449), "0.45"); - assert.strictEqual(format(".3f")(0.4449), "0.445"); - assert.strictEqual(format(".5f")(0.444449), "0.44445"); - assert.strictEqual(format(".1f")(100), "100.0"); - assert.strictEqual(format(".2f")(100), "100.00"); - assert.strictEqual(format(".3f")(100), "100.000"); - assert.strictEqual(format(".5f")(100), "100.00000"); - }, - "can output general notation": function(format) { - assert.strictEqual(format(".1g")(0.049), "0.05"); - assert.strictEqual(format(".1g")(0.49), "0.5"); - assert.strictEqual(format(".2g")(0.449), "0.45"); - assert.strictEqual(format(".3g")(0.4449), "0.445"); - assert.strictEqual(format(".5g")(0.444449), "0.44445"); - assert.strictEqual(format(".1g")(100), "1e+2"); - assert.strictEqual(format(".2g")(100), "1.0e+2"); - assert.strictEqual(format(".3g")(100), "100"); - assert.strictEqual(format(".5g")(100), "100.00"); - assert.strictEqual(format(".5g")(100.2), "100.20"); - assert.strictEqual(format(".2g")(0.002), "0.0020"); - }, - "can output exponent notation ": function(format) { - var f = format("e"); - assert.strictEqual(f(0), "0e+0"); - assert.strictEqual(f(42), "4.2e+1"); - assert.strictEqual(f(42000000), "4.2e+7"); - assert.strictEqual(f(420000000), "4.2e+8"); - assert.strictEqual(f(-4), "-4e+0"); - assert.strictEqual(f(-42), "-4.2e+1"); - assert.strictEqual(f(-4200000), "-4.2e+6"); - assert.strictEqual(f(-42000000), "-4.2e+7"); - }, - "can output SI prefix notation": function(format) { - var f = format("s"); - assert.strictEqual(f(0), "0"); - assert.strictEqual(f(1), "1"); - assert.strictEqual(f(10), "10"); - assert.strictEqual(f(100), "100"); - assert.strictEqual(f(999.5), "999.5"); - assert.strictEqual(f(999500), "999.5k"); - assert.strictEqual(f(1000), "1k"); - assert.strictEqual(f(1400), "1.4k"); - assert.strictEqual(f(1500.5), "1.5005k"); - assert.strictEqual(f(.000001), "1µ"); - }, - "can output SI prefix notation with appropriate rounding": function(format) { - var f = format(".3s"); - assert.strictEqual(f(0), "0.00"); - assert.strictEqual(f(1), "1.00"); - assert.strictEqual(f(10), "10.0"); - assert.strictEqual(f(100), "100"); - assert.strictEqual(f(999.5), "1.00k"); - assert.strictEqual(f(999500), "1.00M"); - assert.strictEqual(f(1000), "1.00k"); - assert.strictEqual(f(1500.5), "1.50k"); - assert.strictEqual(f(145500000), "146M"); - assert.strictEqual(f(145999999.999999347), "146M"); - assert.strictEqual(f(1e26), "100Y"); - assert.strictEqual(f(.000001), "1.00µ"); - assert.strictEqual(f(.009995), "0.0100"); - var f = format(".4s"); - assert.strictEqual(f(999.5), "999.5"); - assert.strictEqual(f(999500), "999.5k"); - assert.strictEqual(f(.009995), "9.995m"); - }, - "can output a currency": function(format) { - var f = format("$"); - assert.strictEqual(f(0), "$0"); - assert.strictEqual(f(.042), "$0.042"); - assert.strictEqual(f(.42), "$0.42"); - assert.strictEqual(f(4.2), "$4.2"); - assert.strictEqual(f(-.042), "-$0.042"); - assert.strictEqual(f(-.42), "-$0.42"); - assert.strictEqual(f(-4.2), "-$4.2"); - }, - "can output a currency with comma-grouping and sign": function(format) { - var f = format("+$,.2f"); - assert.strictEqual(f(0), "+$0.00"); - assert.strictEqual(f(0.429), "+$0.43"); - assert.strictEqual(f(-0.429), "-$0.43"); - assert.strictEqual(f(-1), "-$1.00"); - assert.strictEqual(f(1e4), "+$10,000.00"); - }, - "can output a currency with si-prefix notation": function(format) { - var f = format("$.2s"); - assert.strictEqual(f(0), "$0.0"); - assert.strictEqual(f(2.5e5), "$250k"); - assert.strictEqual(f(-2.5e8), "-$250M"); - assert.strictEqual(f(2.5e11), "$250G"); - }, - "can output a percentage": function(format) { - var f = format("%"); - assert.strictEqual(f(0), "0%"); - assert.strictEqual(f(.042), "4%"); - assert.strictEqual(f(.42), "42%"); - assert.strictEqual(f(4.2), "420%"); - assert.strictEqual(f(-.042), "-4%"); - assert.strictEqual(f(-.42), "-42%"); - assert.strictEqual(f(-4.2), "-420%"); - }, - "can output a percentage with rounding and sign": function(format) { - var f = format("+.2p"); - assert.strictEqual(f(.00123), "+0.12%"); - assert.strictEqual(f(.0123), "+1.2%"); - assert.strictEqual(f(.123), "+12%"); - assert.strictEqual(f(1.23), "+120%"); - assert.strictEqual(f(-.00123), "-0.12%"); - assert.strictEqual(f(-.0123), "-1.2%"); - assert.strictEqual(f(-.123), "-12%"); - assert.strictEqual(f(-1.23), "-120%"); - }, - "can round to significant digits": function(format) { - assert.strictEqual(format(".2r")(0), "0.0"); - assert.strictEqual(format(".1r")(0.049), "0.05"); - assert.strictEqual(format(".1r")(-0.049), "-0.05"); - assert.strictEqual(format(".1r")(0.49), "0.5"); - assert.strictEqual(format(".1r")(-0.49), "-0.5"); - assert.strictEqual(format(".2r")(0.449), "0.45"); - assert.strictEqual(format(".3r")(0.4449), "0.445"); - assert.strictEqual(format(".3r")(1.00), "1.00"); - assert.strictEqual(format(".3r")(0.9995), "1.00"); - assert.strictEqual(format(".5r")(0.444449), "0.44445"); - assert.strictEqual(format("r")(123.45), "123.45"); - assert.strictEqual(format(".1r")(123.45), "100"); - assert.strictEqual(format(".2r")(123.45), "120"); - assert.strictEqual(format(".3r")(123.45), "123"); - assert.strictEqual(format(".4r")(123.45), "123.5"); - assert.strictEqual(format(".5r")(123.45), "123.45"); - assert.strictEqual(format(".6r")(123.45), "123.450"); - assert.strictEqual(format(".1r")(.9), "0.9"); - assert.strictEqual(format(".1r")(.09), "0.09"); - assert.strictEqual(format(".1r")(.949), "0.9"); - assert.strictEqual(format(".1r")(.0949), "0.09"); - assert.strictEqual(format(".10r")(.9999999999), "0.9999999999"); - assert.strictEqual(format(".15r")(.999999999999999), "0.999999999999999"); - }, - "can round very small numbers": function(format) { - var f = format(".2r"); - assert.strictEqual(f(1e-22), "0.00000000000000000000"); - }, - "can group thousands": function(format) { - var f = format(",d"); - assert.strictEqual(f(0), "0"); - assert.strictEqual(f(42), "42"); - assert.strictEqual(f(42000000), "42,000,000"); - assert.strictEqual(f(420000000), "420,000,000"); - assert.strictEqual(f(-4), "-4"); - assert.strictEqual(f(-42), "-42"); - assert.strictEqual(f(-4200000), "-4,200,000"); - assert.strictEqual(f(-42000000), "-42,000,000"); - }, - "can group thousands and zero fill": function(format) { - assert.strictEqual(format("01,d")(0), "0"); - assert.strictEqual(format("01,d")(0), "0"); - assert.strictEqual(format("02,d")(0), "00"); - assert.strictEqual(format("03,d")(0), "000"); - assert.strictEqual(format("05,d")(0), "0,000"); - assert.strictEqual(format("08,d")(0), "0,000,000"); - assert.strictEqual(format("013,d")(0), "0,000,000,000"); - assert.strictEqual(format("021,d")(0), "0,000,000,000,000,000"); - assert.strictEqual(format("013,d")(-42000000), "-0,042,000,000"); - }, - "can group thousands and zero fill with overflow": function(format) { - assert.strictEqual(format("01,d")(1), "1"); - assert.strictEqual(format("01,d")(1), "1"); - assert.strictEqual(format("02,d")(12), "12"); - assert.strictEqual(format("03,d")(123), "123"); - assert.strictEqual(format("05,d")(12345), "12,345"); - assert.strictEqual(format("08,d")(12345678), "12,345,678"); - assert.strictEqual(format("013,d")(1234567890123), "1,234,567,890,123"); - }, - "can group thousands and space fill": function(format) { - assert.strictEqual(format("1,d")(0), "0"); - assert.strictEqual(format("1,d")(0), "0"); - assert.strictEqual(format("2,d")(0), " 0"); - assert.strictEqual(format("3,d")(0), " 0"); - assert.strictEqual(format("5,d")(0), " 0"); - assert.strictEqual(format("8,d")(0), " 0"); - assert.strictEqual(format("13,d")(0), " 0"); - assert.strictEqual(format("21,d")(0), " 0"); - }, - "can group thousands and space fill with overflow": function(format) { - assert.strictEqual(format("1,d")(1), "1"); - assert.strictEqual(format("1,d")(1), "1"); - assert.strictEqual(format("2,d")(12), "12"); - assert.strictEqual(format("3,d")(123), "123"); - assert.strictEqual(format("5,d")(12345), "12,345"); - assert.strictEqual(format("8,d")(12345678), "12,345,678"); - assert.strictEqual(format("13,d")(1234567890123), "1,234,567,890,123"); - }, - "can group thousands with general notation": function(format) { - var f = format(",g"); - assert.strictEqual(f(0), "0"); - assert.strictEqual(f(42), "42"); - assert.strictEqual(f(42000000), "42,000,000"); - assert.strictEqual(f(420000000), "420,000,000"); - assert.strictEqual(f(-4), "-4"); - assert.strictEqual(f(-42), "-42"); - assert.strictEqual(f(-4200000), "-4,200,000"); - assert.strictEqual(f(-42000000), "-42,000,000"); - }, - "can group thousands, space fill, and round to significant digits": function(format) { - assert.strictEqual(format("10,.1f")(123456.49), " 123,456.5"); - assert.strictEqual(format("10,.2f")(1234567.449), "1,234,567.45"); - assert.strictEqual(format("10,.3f")(12345678.4449), "12,345,678.445"); - assert.strictEqual(format("10,.5f")(123456789.444449), "123,456,789.44445"); - assert.strictEqual(format("10,.1f")(123456), " 123,456.0"); - assert.strictEqual(format("10,.2f")(1234567), "1,234,567.00"); - assert.strictEqual(format("10,.3f")(12345678), "12,345,678.000"); - assert.strictEqual(format("10,.5f")(123456789), "123,456,789.00000"); - }, - "can display integers in fixed-point notation": function(format) { - assert.strictEqual(format("f")(42), "42"); - }, - "will not display non-integers in integer format": function(format) { - assert.strictEqual(format("d")(4.2), ""); - }, - "unicode character": function(format) { - assert.strictEqual(format("c")(9731), "☃"); - }, - "binary": function(format) { - assert.strictEqual(format("b")(10), "1010"); - }, - "binary with prefix": function(format) { - assert.strictEqual(format("#b")(10), "0b1010"); - }, - "octal": function(format) { - assert.strictEqual(format("o")(10), "12"); - }, - "octal with prefix": function(format) { - assert.strictEqual(format("#o")(10), "0o12"); - }, - "hexadecimal (lowercase)": function(format) { - assert.strictEqual(format("x")(3735928559), "deadbeef"); - }, - "hexadecimal (lowercase) with prefix": function(format) { - assert.strictEqual(format("#x")(3735928559), "0xdeadbeef"); - }, - "hexadecimal (uppercase)": function(format) { - assert.strictEqual(format("X")(3735928559), "DEADBEEF"); - }, - "hexadecimal (uppercase) with prefix": function(format) { - assert.strictEqual(format("#X")(3735928559), "0xDEADBEEF"); - }, - "fill respects prefix": function(format) { - assert.strictEqual(format("#20x")(3735928559), " 0xdeadbeef"); - }, - "align left": function(format) { - assert.strictEqual(format("<1,d")(0), "0"); - assert.strictEqual(format("<1,d")(0), "0"); - assert.strictEqual(format("<2,d")(0), "0 "); - assert.strictEqual(format("<3,d")(0), "0 "); - assert.strictEqual(format("<5,d")(0), "0 "); - assert.strictEqual(format("<8,d")(0), "0 "); - assert.strictEqual(format("<13,d")(0), "0 "); - assert.strictEqual(format("<21,d")(0), "0 "); - }, - "align right": function(format) { - assert.strictEqual(format(">1,d")(0), "0"); - assert.strictEqual(format(">1,d")(0), "0"); - assert.strictEqual(format(">2,d")(0), " 0"); - assert.strictEqual(format(">3,d")(0), " 0"); - assert.strictEqual(format(">5,d")(0), " 0"); - assert.strictEqual(format(">8,d")(0), " 0"); - assert.strictEqual(format(">13,d")(0), " 0"); - assert.strictEqual(format(">21,d")(0), " 0"); - }, - "align center": function(format) { - assert.strictEqual(format("^1,d")(0), "0"); - assert.strictEqual(format("^1,d")(0), "0"); - assert.strictEqual(format("^2,d")(0), " 0"); - assert.strictEqual(format("^3,d")(0), " 0 "); - assert.strictEqual(format("^5,d")(0), " 0 "); - assert.strictEqual(format("^8,d")(0), " 0 "); - assert.strictEqual(format("^13,d")(0), " 0 "); - assert.strictEqual(format("^21,d")(0), " 0 "); - }, - "pad after sign": function(format) { - assert.strictEqual(format("=+1,d")(0), "+0"); - assert.strictEqual(format("=+1,d")(0), "+0"); - assert.strictEqual(format("=+2,d")(0), "+0"); - assert.strictEqual(format("=+3,d")(0), "+ 0"); - assert.strictEqual(format("=+5,d")(0), "+ 0"); - assert.strictEqual(format("=+8,d")(0), "+ 0"); - assert.strictEqual(format("=+13,d")(0), "+ 0"); - assert.strictEqual(format("=+21,d")(0), "+ 0"); - }, - "a space can denote positive numbers": function(format) { - assert.strictEqual(format(" 1,d")(-1), "-1"); - assert.strictEqual(format(" 1,d")(0), " 0"); - assert.strictEqual(format(" 2,d")(0), " 0"); - assert.strictEqual(format(" 3,d")(0), " 0"); - assert.strictEqual(format(" 5,d")(0), " 0"); - assert.strictEqual(format(" 8,d")(0), " 0"); - assert.strictEqual(format(" 13,d")(0), " 0"); - assert.strictEqual(format(" 21,d")(0), " 0"); - }, - "can format negative zero": function(format) { - assert.strictEqual(format("1d")(-0), "-0"); - assert.strictEqual(format("1f")(-0), "-0"); - }, - "supports \"n\" as an alias for \",g\"": function(format) { - var f = format("n"); - assert.strictEqual(f(.0042), "0.0042"); - assert.strictEqual(f(.42), "0.42"); - assert.strictEqual(f(0), "0"); - assert.strictEqual(f(42), "42"); - assert.strictEqual(f(42000000), "42,000,000"); - assert.strictEqual(f(420000000), "420,000,000"); - assert.strictEqual(f(-4), "-4"); - assert.strictEqual(f(-42), "-42"); - assert.strictEqual(f(-4200000), "-4,200,000"); - assert.strictEqual(f(-42000000), "-42,000,000"); - }, - "unreasonable precision values are clamped to reasonable values": function(format) { - assert.strictEqual(format(".30f")(0), "0.00000000000000000000"); - assert.strictEqual(format(".0g")(1), "1"); - assert.strictEqual(format(",.-1f")(12345), "12,345"); - assert.strictEqual(format("+,.-1%")(123.45), "+12,345%"); - } - } -}); - -suite.export(module); diff --git a/test/format/formatPrefix-test.js b/test/format/formatPrefix-test.js deleted file mode 100644 index 63c11f81cd88c9..00000000000000 --- a/test/format/formatPrefix-test.js +++ /dev/null @@ -1,112 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.formatPrefix"); - -suite.addBatch({ - "formatPrefix": { - topic: load("format/formatPrefix").expression("d3.formatPrefix"), - "determines the appropriate prefix for small numbers": function(prefix) { - assert.equal(prefix(0).symbol, ""); - assert.equal(prefix(1e-00).symbol, ""); - assert.equal(prefix(1e-01).symbol, ""); - assert.equal(prefix(1e-02).symbol, ""); - assert.equal(prefix(1e-03).symbol, "m"); - assert.equal(prefix(1e-04).symbol, "m"); - assert.equal(prefix(1e-05).symbol, "m"); - assert.equal(prefix(1e-06).symbol, "µ"); - assert.equal(prefix(1e-07).symbol, "µ"); - assert.equal(prefix(1e-08).symbol, "µ"); - assert.equal(prefix(1e-09).symbol, "n"); - assert.equal(prefix(1e-10).symbol, "n"); - assert.equal(prefix(1e-11).symbol, "n"); - assert.equal(prefix(1e-12).symbol, "p"); - assert.equal(prefix(1e-13).symbol, "p"); - assert.equal(prefix(1e-14).symbol, "p"); - assert.equal(prefix(1e-15).symbol, "f"); - assert.equal(prefix(1e-16).symbol, "f"); - assert.equal(prefix(1e-17).symbol, "f"); - assert.equal(prefix(1e-18).symbol, "a"); - assert.equal(prefix(1e-19).symbol, "a"); - assert.equal(prefix(1e-20).symbol, "a"); - assert.equal(prefix(1e-21).symbol, "z"); - assert.equal(prefix(1e-22).symbol, "z"); - assert.equal(prefix(1e-23).symbol, "z"); - assert.equal(prefix(1e-24).symbol, "y"); - assert.equal(prefix(1e-25).symbol, "y"); - assert.equal(prefix(1e-26).symbol, "y"); - assert.equal(prefix(1e-27).symbol, "y"); - }, - "determines the appropriate prefix for large numbers": function(prefix) { - assert.equal(prefix(0).symbol, ""); - assert.equal(prefix(1e00).symbol, ""); - assert.equal(prefix(1e01).symbol, ""); - assert.equal(prefix(1e02).symbol, ""); - assert.equal(prefix(1e03).symbol, "k"); - assert.equal(prefix(1e04).symbol, "k"); - assert.equal(prefix(1e05).symbol, "k"); - assert.equal(prefix(1e06).symbol, "M"); - assert.equal(prefix(1e07).symbol, "M"); - assert.equal(prefix(1e08).symbol, "M"); - assert.equal(prefix(1e09).symbol, "G"); - assert.equal(prefix(1e10).symbol, "G"); - assert.equal(prefix(1e11).symbol, "G"); - assert.equal(prefix(1e12).symbol, "T"); - assert.equal(prefix(1e13).symbol, "T"); - assert.equal(prefix(1e14).symbol, "T"); - assert.equal(prefix(1e15).symbol, "P"); - assert.equal(prefix(1e16).symbol, "P"); - assert.equal(prefix(1e17).symbol, "P"); - assert.equal(prefix(1e18).symbol, "E"); - assert.equal(prefix(1e19).symbol, "E"); - assert.equal(prefix(1e20).symbol, "E"); - assert.equal(prefix(1e21).symbol, "Z"); - assert.equal(prefix(1e22).symbol, "Z"); - assert.equal(prefix(1e23).symbol, "Z"); - assert.equal(prefix(1e24).symbol, "Y"); - assert.equal(prefix(1e25).symbol, "Y"); - assert.equal(prefix(1e26).symbol, "Y"); - assert.equal(prefix(1e27).symbol, "Y"); - }, - "determines the appropriate prefix for negative numbers": function(prefix) { - assert.equal(prefix(-0).symbol, ""); - assert.equal(prefix(-1e-00).symbol, ""); - assert.equal(prefix(-1e-03).symbol, "m"); - assert.equal(prefix(-1e-06).symbol, "µ"); - assert.equal(prefix(-1e-09).symbol, "n"); - assert.equal(prefix(-1e-12).symbol, "p"); - assert.equal(prefix(-1e-15).symbol, "f"); - assert.equal(prefix(-1e-18).symbol, "a"); - assert.equal(prefix(-1e-21).symbol, "z"); - assert.equal(prefix(-1e-24).symbol, "y"); - assert.equal(prefix(-1e-27).symbol, "y"); - assert.equal(prefix(-1e00).symbol, ""); - assert.equal(prefix(-1e03).symbol, "k"); - assert.equal(prefix(-1e06).symbol, "M"); - assert.equal(prefix(-1e09).symbol, "G"); - assert.equal(prefix(-1e12).symbol, "T"); - assert.equal(prefix(-1e15).symbol, "P"); - assert.equal(prefix(-1e18).symbol, "E"); - assert.equal(prefix(-1e21).symbol, "Z"); - assert.equal(prefix(-1e24).symbol, "Y"); - assert.equal(prefix(-1e27).symbol, "Y"); - }, - "considers the effect of rounding based on precision": function(prefix) { - assert.equal(prefix(999.5000000, 4).symbol, ""); - assert.equal(prefix(999.5000000, 3).symbol, "k"); - assert.equal(prefix(995.0000000, 3).symbol, ""); - assert.equal(prefix(995.0000000, 2).symbol, "k"); - assert.equal(prefix(950.0000000, 2).symbol, ""); - assert.equal(prefix(950.0000000, 1).symbol, "k"); - assert.equal(prefix(0.000009995, 4).symbol, "µ"); - assert.equal(prefix(0.000009995, 3).symbol, "m"); - assert.equal(prefix(0.000009950, 3).symbol, "µ"); - assert.equal(prefix(0.000009950, 2).symbol, "m"); - assert.equal(prefix(0.000009500, 2).symbol, "µ"); - assert.equal(prefix(0.000009500, 1).symbol, "m"); - } - } -}); - -suite.export(module); diff --git a/test/format/requote-test.js b/test/format/requote-test.js deleted file mode 100644 index 4c727f98c54c4d..00000000000000 --- a/test/format/requote-test.js +++ /dev/null @@ -1,49 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.requote"); - -suite.addBatch({ - "requote": { - topic: load("format/requote").expression("d3.requote"), - "quotes backslashes": function(requote) { - assert.equal(requote("\\"), "\\\\"); - }, - "quotes carets": function(requote) { - assert.equal(requote("^"), "\\^"); - }, - "quotes dollar signs": function(requote) { - assert.equal(requote("$"), "\\$"); - }, - "quotes stars": function(requote) { - assert.equal(requote("*"), "\\*"); - }, - "quotes plusses": function(requote) { - assert.equal(requote("+"), "\\+"); - }, - "quotes question marks": function(requote) { - assert.equal(requote("?"), "\\?"); - }, - "quotes periods": function(requote) { - assert.equal(requote("."), "\\."); - }, - "quotes parentheses": function(requote) { - assert.equal(requote("("), "\\("); - assert.equal(requote(")"), "\\)"); - }, - "quotes pipes": function(requote) { - assert.equal(requote("|"), "\\|"); - }, - "quotes curly braces": function(requote) { - assert.equal(requote("{"), "\\{"); - assert.equal(requote("}"), "\\}"); - }, - "quotes square brackets": function(requote) { - assert.equal(requote("["), "\\["); - assert.equal(requote("]"), "\\]"); - } - } -}); - -suite.export(module); diff --git a/test/format/round-test.js b/test/format/round-test.js deleted file mode 100644 index 0f70c48d0a23cf..00000000000000 --- a/test/format/round-test.js +++ /dev/null @@ -1,66 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.round"); - -suite.addBatch({ - "round": { - topic: load("format/round").expression("d3.round"), - "returns a number": function(round) { - assert.isNumber(round(42)); - }, - "returns zero for zero": function(round) { - assert.equal(round(0), 0); - }, - "ignores degenerate input": function(round) { - assert.isNaN(round(NaN)); - assert.equal(round(Infinity), Infinity); - assert.equal(round(-Infinity), -Infinity); - }, - "returns integers by default": function(round) { - assert.equal(round(10.6), 11); - assert.equal(round(10.4), 10); - assert.equal(round(0.6), 1); - assert.equal(round(0.4), 0); - assert.equal(round(-0.6), -1); - assert.equal(round(-0.4), 0); - assert.equal(round(-10.6), -11); - assert.equal(round(-10.4), -10); - }, - "rounds to the specified decimal place": function(round) { - assert.inDelta(round(10.56, 1), 10.6, 1e-6); - assert.inDelta(round(10.54, 1), 10.5, 1e-6); - assert.inDelta(round(0.56, 1), 0.6, 1e-6); - assert.inDelta(round(0.54, 1), 0.5, 1e-6); - assert.inDelta(round(-0.56, 1), -0.6, 1e-6); - assert.inDelta(round(-0.54, 1), -0.5, 1e-6); - assert.inDelta(round(-10.56, 1), -10.6, 1e-6); - assert.inDelta(round(-10.54, 1), -10.5, 1e-6); - assert.inDelta(round(10.556, 2), 10.56, 1e-6); - assert.inDelta(round(10.554, 2), 10.55, 1e-6); - assert.inDelta(round(0.556, 2), 0.56, 1e-6); - assert.inDelta(round(0.554, 2), 0.55, 1e-6); - assert.inDelta(round(-0.556, 2), -0.56, 1e-6); - assert.inDelta(round(-0.554, 2), -0.55, 1e-6); - assert.inDelta(round(-10.556, 2), -10.56, 1e-6); - assert.inDelta(round(-10.554, 2), -10.55, 1e-6); - }, - "rounds to the specified significant digits": function(round) { - assert.equal(round(123.45, -1), 120); - assert.equal(round(345.67, -1), 350); - assert.equal(round(-123.45, -1), -120); - assert.equal(round(-345.67, -1), -350); - assert.equal(round(123.45, -2), 100); - assert.equal(round(456.78, -2), 500); - assert.equal(round(-123.45, -2), -100); - assert.equal(round(-456.78, -2), -500); - assert.equal(round(123.45, -3), 0); - assert.equal(round(567.89, -3), 1000); - assert.equal(round(-123.45, -3), 0); - assert.equal(round(-567.89, -3), -1000); - } - } -}); - -suite.export(module); diff --git a/test/geo/albers-test.js b/test/geo/albers-test.js deleted file mode 100644 index 15afa25db25f9d..00000000000000 --- a/test/geo/albers-test.js +++ /dev/null @@ -1,40 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.albers"); - -suite.addBatch({ - "albers": { - topic: load("geo/albers").expression("d3.geo.albers"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); }, - "has the parallels 29.5°, 45.5°": function(p) { - assert.inDelta(p.parallels(), [29.5, 45.5], 1e-6); - }, - "has the rotation 96°, 0°": function(p) { - assert.inDelta(p.rotate(), [96, 0, 0], 1e-6); - }, - "has the center -0.6°, 38.7°": function(p) { - assert.inDelta(p.center(), [-.6, 38.7], 1e-6); - }, - "has the scale 1070": function(p) { - assert.inDelta(p.scale(), 1070, 1e-6); - } - }, { - "Washington, DC": [[-120.50000000, 47.50000000], [ 181.00023857, 45.12748866]], - "San Francisco, CA": [[-122.42000000, 37.78000000], [ 107.44485839, 214.04820561]], - "the North Pole": [[ 0.00000000, 90.00000000], [1062.11670525, -761.71949818]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Washington, DC": [[-120.50000000, 47.50000000], [ -0.27943903, -0.19146964]], - "San Francisco, CA": [[-122.42000000, 37.78000000], [ -0.34818238, -0.03359981]], - "the North Pole": [[ 0.00000000, 90.00000000], [ 0.54403430, -0.94553224]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/albers-usa-test.js b/test/geo/albers-usa-test.js deleted file mode 100644 index 38db0b0832fc5e..00000000000000 --- a/test/geo/albers-usa-test.js +++ /dev/null @@ -1,33 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.albersUsa"); - -suite.addBatch({ - "albersUsa": { - topic: load("geo/albers-usa").expression("d3.geo.albersUsa"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); }, - "has the scale 1070": function(p) { - assert.inDelta(p.scale(), 1070, 1e-6); - } - }, { - "Washington, DC": [[-120.50000000, 47.50000000], [ 181.00023857, 45.12748866]], - "San Francisco, CA": [[-122.42000000, 37.78000000], [ 107.44485839, 214.04820561]], - "Juneau, AK": [[-134.22000000, 58.43000000], [ 224.79015007, 455.65860760]], - "Honolulu, HI": [[-157.82000000, 21.30000000], [ 299.14918225, 451.11762634]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Washington, DC": [[-120.50000000, 47.50000000], [ -0.27943903, -0.19146964]], - "San Francisco, CA": [[-122.42000000, 37.78000000], [ -0.34818238, -0.03359981]], - "Juneau, AK": [[-134.22000000, 58.43000000], [ -0.23851388, 0.19220431]], - "Honolulu, HI": [[-157.82000000, 21.30000000], [ -0.16901946, 0.18796040]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/area-benchmark.js b/test/geo/area-benchmark.js deleted file mode 100644 index 4d44b09177a04e..00000000000000 --- a/test/geo/area-benchmark.js +++ /dev/null @@ -1,12 +0,0 @@ -var d3 = require("../../"); - -var formatNumber = d3.format(",.02r"), - o = d3.geo.circle().angle(30).precision(.1)(), - n = 1e3, - then = Date.now(); - -for (var i = 0; i < n; i++) { - d3.geo.area(o); -} - -console.log("circle.angle(30°): " + formatNumber((Date.now() - then) / i) + "ms/op."); diff --git a/test/geo/area-test.js b/test/geo/area-test.js deleted file mode 100644 index aacb5a23febd5c..00000000000000 --- a/test/geo/area-test.js +++ /dev/null @@ -1,185 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.area"); - -var π = Math.PI; - -suite.addBatch({ - "area": { - topic: load("geo/area").expression("d3.geo.area"), - "Point": function(area) { - assert.equal(area({type: "Point", coordinates: [0, 0]}), 0); - }, - "MultiPoint": function(area) { - assert.equal(area({type: "MultiPoint", coordinates: [[0, 1], [2, 3]]}), 0); - }, - "LineString": function(area) { - assert.equal(area({type: "LineString", coordinates: [[0, 1], [2, 3]]}), 0); - }, - "MultiLineString": function(area) { - assert.equal(area({type: "MultiLineString", coordinates: [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]}), 0); - }, - "Polygon": { - "tiny": function(area) { - assert.inDelta(area({type: "Polygon", coordinates: [[ - [-64.66070178517852, 18.33986913231323], - [-64.66079715091509, 18.33994007490749], - [-64.66074946804680, 18.33994007490749], - [-64.66070178517852, 18.33986913231323] - ]]}), 4.890516e-13, 1e-13); - }, - "zero area": function(area) { - assert.equal(area({ - "type": "Polygon", - "coordinates": [[ - [96.79142432523281, 5.262704519048153], - [96.81065389253769, 5.272455576551362], - [96.82988345984256, 5.272455576551362], - [96.81065389253769, 5.272455576551362], - [96.79142432523281, 5.262704519048153] - ]] - }), 0); - }, - "semilune": function(area) { - assert.inDelta(area({type: "Polygon", coordinates: [[[0, 0], [0, 90], [90, 0], [0, 0]]]}), π / 2, 1e-6); - }, - "lune": function(area) { - assert.equal(area({type: "Polygon", coordinates: [[[0, 0], [0, 90], [90, 0], [0, -90], [0, 0]]]}), π); - }, - "hemispheres": { - "North": function(area) { - assert.inDelta(area({type: "Polygon", coordinates: [[[0, 0], [-90, 0], [180, 0], [90, 0], [0, 0]]]}), 2 * π, 1e-6); - }, - "South": function(area) { - assert.inDelta(area({type: "Polygon", coordinates: [[[0, 0], [90, 0], [180, 0], [-90, 0], [0, 0]]]}), 2 * π, 1e-6); - }, - "East": function(area) { - assert.equal(area({type: "Polygon", coordinates: [[[0, 0], [0, 90], [180, 0], [0, -90], [0, 0]]]}), 2 * π); - }, - "West": function(area) { - assert.equal(area({type: "Polygon", coordinates: [[[0, 0], [0, -90], [180, 0], [0, 90], [0, 0]]]}), 2 * π); - } - }, - "graticule outline": { - "sphere": function(area) { - assert.inDelta(area(_.geo.graticule().extent([[-180, -90], [180, 90]]).outline()), 4 * π, 1e-5); - }, - "hemisphere": function(area) { - assert.inDelta(area(_.geo.graticule().extent([[-180, 0], [180, 90]]).outline()), 2 * π, 1e-5); - }, - "semilune": function(area) { - assert.inDelta(area(_.geo.graticule().extent([[0, 0], [90, 90]]).outline()), π / 2, 1e-5); - } - }, - "circles": { - "hemisphere": function(area) { - assert.inDelta(area(_.geo.circle().angle(90)()), 2 * π, 1e-5); - }, - "60°": function(area) { - assert.inDelta(area(_.geo.circle().angle(60).precision(.1)()), π, 1e-5); - }, - "60° North": function(area) { - assert.inDelta(area(_.geo.circle().angle(60).precision(.1).origin([0, 90])()), π, 1e-5); - }, - "45°": function(area) { - assert.inDelta(area(_.geo.circle().angle(45).precision(.1)()), π * (2 - Math.SQRT2), 1e-5); - }, - "45° North": function(area) { - assert.inDelta(area(_.geo.circle().angle(45).precision(.1).origin([0, 90])()), π * (2 - Math.SQRT2), 1e-5); - }, - "45° South": function(area) { - assert.inDelta(area(_.geo.circle().angle(45).precision(.1).origin([0, -90])()), π * (2 - Math.SQRT2), 1e-5); - }, - "135°": function(area) { - assert.inDelta(area(_.geo.circle().angle(135).precision(.1)()), π * (2 + Math.SQRT2), 1e-5); - }, - "135° North": function(area) { - assert.inDelta(area(_.geo.circle().angle(135).precision(.1).origin([0, 90])()), π * (2 + Math.SQRT2), 1e-5); - }, - "135° South": function(area) { - assert.inDelta(area(_.geo.circle().angle(135).precision(.1).origin([0, -90])()), π * (2 + Math.SQRT2), 1e-5); - }, - "tiny": function(area) { - assert.inDelta(area(_.geo.circle().angle(1e-6).precision(.1)()), 0, 1e-6); - }, - "huge": function(area) { - assert.inDelta(area(_.geo.circle().angle(180 - 1e-6).precision(.1)()), 4 * π, 1e-6); - }, - "60° with 45° hole": function(area) { - var circle = _.geo.circle().precision(.1); - assert.inDelta(area({ - type: "Polygon", - coordinates: [ - circle.angle(60)().coordinates[0], - circle.angle(45)().coordinates[0].reverse() - ] - }), π * (Math.SQRT2 - 1), 1e-5); - }, - "45° holes at [0°, 0°] and [0°, 90°]": function(area) { - var circle = _.geo.circle().precision(.1).angle(45); - assert.inDelta(area({ - type: "Polygon", - coordinates: [ - circle.origin([0, 0])().coordinates[0].reverse(), - circle.origin([0, 90])().coordinates[0].reverse() - ] - }), π * 2 * Math.SQRT2, 1e-5); - }, - "45° holes at [0°, 90°] and [0°, 0°]": function(area) { - var circle = _.geo.circle().precision(.1).angle(45); - assert.inDelta(area({ - type: "Polygon", - coordinates: [ - circle.origin([0, 90])().coordinates[0].reverse(), - circle.origin([0, 0])().coordinates[0].reverse() - ] - }), π * 2 * Math.SQRT2, 1e-5); - } - }, - "stripes": { - "45°, -45°": function(area) { - assert.inDelta(area(stripes(45, -45)), π * 2 * Math.SQRT2, 1e-5); - }, - "-45°, 45°": function(area) { - assert.inDelta(area(stripes(-45, 45)), π * 2 * (2 - Math.SQRT2), 1e-5); - }, - "45°, 30°": function(area) { - assert.inDelta(area(stripes(45, 30)), π * (Math.SQRT2 - 1), 1e-5); - } - } - }, - "MultiPolygon": { - "two hemispheres": function(area) { - assert.equal(area({type: "MultiPolygon", coordinates: [ - [[[0, 0], [-90, 0], [180, 0], [90, 0], [0, 0]]], - [[[0, 0], [90, 0], [180, 0], [-90, 0], [0, 0]]] - ]}), 4 * π); - } - }, - "Sphere": function(area) { - assert.equal(area({type: "Sphere"}), 4 * π); - }, - "GeometryCollection": function(area) { - assert.equal(area({type: "GeometryCollection", geometries: [{type: "Sphere"}]}), 4 * π); - }, - "FeatureCollection": function(area) { - assert.equal(area({type: "FeatureCollection", features: [{type: "Feature", geometry: {type: "Sphere"}}]}), 4 * π); - }, - "Feature": function(area) { - assert.equal(area({type: "Feature", geometry: {type: "Sphere"}}), 4 * π); - } - } -}); - -suite.export(module); - -function stripes(a, b) { - return {type: "Polygon", coordinates: [a, b].map(function(d, i) { - var stripe = _.range(-180, 180, .1).map(function(x) { return [x, d]; }); - stripe.push(stripe[0]); - return i ? stripe.reverse() : stripe; - })}; -} diff --git a/test/geo/azimuthal-equal-area-test.js b/test/geo/azimuthal-equal-area-test.js deleted file mode 100644 index 9199c3309fb3fd..00000000000000 --- a/test/geo/azimuthal-equal-area-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.azimuthalEqualArea"); - -suite.addBatch({ - "azimuthalEqualArea": { - topic: load("geo/azimuthal-equal-area").expression("d3.geo.azimuthalEqualArea"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 470.78325089, 51.18095336]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 448.09318291, 57.65281089]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 484.55622556, 96.45697185]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 428.30355841, 405.56446813]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 499.82677711, 55.68926131]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 452.67706228]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 47.32293772]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.06144499, -1.32546031]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.21271211, -1.28231459]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.03037484, -1.02362019]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.34464294, 1.03709645]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.13217851, -1.29540492]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 1.35118042]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -1.35118042]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/azimuthal-equidistant-test.js b/test/geo/azimuthal-equidistant-test.js deleted file mode 100644 index 8ba104db8c1728..00000000000000 --- a/test/geo/azimuthal-equidistant-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.azimuthalEquidistant"); - -suite.addBatch({ - "azimuthalEquidistant": { - topic: load("geo/azimuthal-equidistant").expression("d3.geo.azimuthalEquidistant"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 469.92237700, 32.61061747]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 445.26741926, 40.61796552]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 484.78328535, 88.80514528]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 425.30773539, 414.57947189]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 501.59066113, 38.40245747]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 472.52947963]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 27.47052037]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.06718415, -1.44926255]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.23155054, -1.39588023]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.03188857, -1.07463236]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.36461510, 1.09719648]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.14393774, -1.41065028]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 1.48352986]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -1.48352986]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/benchmark.js b/test/geo/benchmark.js deleted file mode 100644 index f1877d19a17f5b..00000000000000 --- a/test/geo/benchmark.js +++ /dev/null @@ -1,83 +0,0 @@ -var fs = require("fs"), - d3 = require("../../"); - -var formatNumber = d3.format(",.02r"), - projection = d3.geo.stereographic().clipAngle(150), - path = d3.geo.path().projection(projection), - graticule = d3.geo.graticule().step([1, 1]), - circle = d3.geo.circle().angle(30), - n = 10, - o, - then; - -o = circle(); -then = Date.now(); - -for (var i = 0, k = 0; i < n * 1000; i++, k++) { - path(o); -} - -console.log("Single circle: " + formatNumber((Date.now() - then) / k) + "ms/op."); - -o = JSON.parse(fs.readFileSync("./test/data/us-counties.json")).features; -then = Date.now(); - -for (var i = 0, k = 0; i < n; i++, k++) { - for (var j = 0, m = o.length; j < m; ++j) { - path(o[j]); - } -} - -console.log("U.S. counties (separate): " + formatNumber((Date.now() - then) / k) + "ms/op."); - -o = JSON.parse(fs.readFileSync("./test/data/us-counties.json")); -then = Date.now(); - -for (var i = 0, k = 0; i < n; i++, k++) { - path(o); -} - -console.log("U.S. counties: " + formatNumber((Date.now() - then) / k) + "ms/op."); - -o = graticule(); -then = Date.now(); - -for (var i = 0, k = 0; i < n; i++, k++) { - path(o); -} - -console.log("Dense graticule: " + formatNumber((Date.now() - then) / k) + "ms/op."); - -o = {type: "GeometryCollection", geometries: d3.range(-180, 180, 1).map(function(x) { - return circle.origin([x, 0])(); -})}; -then = Date.now(); - -for (var i = 0, k = 0; i < n; i++, k++) { - path(o); -} - -console.log("Circle polygons: " + formatNumber((Date.now() - then) / k) + "ms/op."); - -o = spiral(); -then = Date.now(); - -for (var i = 0, k = 0; i < n; i++, k++) { - path(o); -} - -console.log("Spiral polygons: " + formatNumber((Date.now() - then) / k) + "ms/op."); - -function spiral() { - var n = 1e4, - dy = 5; - - var spiral = d3.range(0, 1 + 1 / n, 1 / n).map(function(t) { - return [(360 * 10 * t) % 360 - 180, -90 + dy + (90 - dy) * 2 * t]; - }).concat(d3.range(1, 0, -1 / n).map(function(t) { - return [(360 * 10 * t) % 360 - 180, -90 + (90 - dy) * 2 * t]; - })); - spiral.push(spiral[0]); - - return {type: "Polygon", coordinates: [spiral]}; -} diff --git a/test/geo/bounds-test.js b/test/geo/bounds-test.js deleted file mode 100644 index d18e347e7540e4..00000000000000 --- a/test/geo/bounds-test.js +++ /dev/null @@ -1,265 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.bounds"); - -suite.addBatch({ - "bounds": { - topic: load("geo/bounds").expression("d3.geo.bounds"), - "Feature": function(bounds) { - assert.deepEqual(bounds({ - type: "Feature", - geometry: { - type: "MultiPoint", - coordinates: [[-123, 39], [-122, 38]] - } - }), [[-123, 38], [-122, 39]]); - }, - "FeatureCollection": function(bounds) { - assert.deepEqual(bounds({ - type: "FeatureCollection", - features: [ - { - type: "Feature", - geometry: { - type: "Point", - coordinates: [-123, 39] - } - }, - { - type: "Feature", - geometry: { - type: "Point", - coordinates: [-122, 38] - } - } - ] - }), [[-123, 38], [-122, 39]]); - }, - "GeometryCollection": function(bounds) { - assert.deepEqual(bounds({ - type: "GeometryCollection", - geometries: [ - { - type: "Point", - coordinates: [-123, 39] - }, - { - type: "Point", - coordinates: [-122, 38] - } - ] - }), [[-123, 38], [-122, 39]]); - }, - "LineString": { - "simple": function(bounds) { - assert.deepEqual(bounds({ - type: "LineString", - coordinates: [[-123, 39], [-122, 38]] - }), [[-123, 38], [-122, 39]]); - }, - "containing coincident points": function(bounds) { - assert.deepEqual(bounds({ - type: "LineString", - coordinates: [[-123, 39], [-122, 38], [-122, 38]] - }), [[-123, 38], [-122, 39]]); - }, - "meridian": function(bounds) { - assert.deepEqual(bounds({ - type: "LineString", - coordinates: [[0, 0], [0, 1], [0, 60]] - }), [[0, 0], [0, 60]]); - }, - "equator": function(bounds) { - assert.deepEqual(bounds({ - type: "LineString", - coordinates: [[0, 0], [1, 0], [60, 0]] - }), [[0, 0], [60, 0]]); - }, - "containing an inflection point": { - "in the Northern hemisphere": function(bounds) { - assert.inDelta(bounds({ - type: "LineString", - coordinates: [[-45, 60], [45, 60]] - }), [[-45, 60], [45, 67.792345]], 1e-6); - }, - "in the Southern hemisphere": function(bounds) { - assert.inDelta(bounds({ - type: "LineString", - coordinates: [[-45, -60], [45, -60]] - }), [[-45, -67.792345], [45, -60]], 1e-6); - } - } - }, - "MultiLineString": function(bounds) { - assert.deepEqual(bounds({ - type: "MultiLineString", - coordinates: [[[-123, 39], [-122, 38]]] - }), [[-123, 38], [-122, 39]]); - }, - "MultiPoint": { - "simple": function(bounds) { - assert.deepEqual(bounds({ - type: "MultiPoint", - coordinates: [[-123, 39], [-122, 38]] - }), [[-123, 38], [-122, 39]]); - }, - "two points near antimeridian": function(bounds) { - assert.deepEqual(bounds({ - type: "MultiPoint", - coordinates: [[-179, 39], [179, 38]] - }), [[179, 38], [-179, 39]]); - }, - "two points near antimeridian, two points near primary meridian": function(bounds) { - assert.deepEqual(bounds({ - type: "MultiPoint", - coordinates: [[-179, 39], [179, 38], [-1, 0], [1, 0]] - }), [[-1, 0], [-179, 39]]); - }, - "two points near primary meridian, two points near antimeridian": function(bounds) { - assert.deepEqual(bounds({ - type: "MultiPoint", - coordinates: [[-1, 0], [1, 0], [-179, 39], [179, 38]] - }), [[-1, 0], [-179, 39]]); - }, - "four mixed points near primary meridian and antimeridian": function(bounds) { - assert.deepEqual(bounds({ - type: "MultiPoint", - coordinates: [[-1, 0], [-179, 39], [1, 0], [179, 38]] - }), [[-1, 0], [-179, 39]]); - }, - "three points near antimeridian": function(bounds) { - assert.deepEqual(bounds({ - type: "MultiPoint", - coordinates: [[178, 38], [179, 39], [-179, 37]] - }), [[178, 37], [-179, 39]]); - }, - "various points near antimeridian": function(bounds) { - assert.deepEqual(bounds({ - type: "MultiPoint", - coordinates: [[-179, 39], [-179, 38], [178, 39], [-178, 38]] - }), [[178, 38], [-178, 39]]); - }, - }, - "MultiPolygon": function(bounds) { - assert.inDelta(bounds({ - type: "MultiPolygon", - coordinates: [ - [[[-123, 39], [-122, 39], [-122, 38], [-123, 39]], - [[10, 20], [20, 20], [20, 10], [10, 10], [10, 20]]] - ] - }), [[-123, 10], [20, 39.001067]], 1e-6); - }, - "Point": function(bounds) { - assert.deepEqual(bounds({ - type: "Point", - coordinates: [-123, 39] - }), [[-123, 39], [-123, 39]]); - }, - "Polygon": { - "simple": function(bounds) { - assert.inDelta(bounds({ - type: "Polygon", - coordinates: [[[-123, 39], [-122, 39], [-122, 38], [-123, 39]]] - }), [[-123, 38], [-122, 39.001067]], 1e-6); - }, - "larger than a hemisphere": { - "small, counter-clockwise": function(bounds) { - assert.deepEqual(bounds({ - type: "Polygon", - coordinates: [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]] - }), [[-180, -90], [180, 90]]); - }, - "large lat-lon rectangle": function(bounds) { - assert.inDelta(bounds({ - type: "Polygon", - coordinates: [[[-170, 80], [0, 80], [170, 80], [170, -80], [0, -80], [-170, -80], [-170, 80]]] - }), [[-170, -89.119552], [170, 89.119552]], 1e-6); - }, - "South pole": function(bounds) { - assert.inDelta(bounds({ - type: "Polygon", - coordinates: [[[10, 80], [170, 80], [-170, 80], [-10, 80], [10, 80]]] - }), [[-180, -90], [180, 88.246216]], 1e-6); - }, - "excluding both poles": function(bounds) { - assert.inDelta(bounds({ - type: "Polygon", - coordinates: [[[10, 80], [170, 80], [-170, 80], [-10, 80], [-10, 0], [-10, -80], [-170, -80], [170, -80], [10, -80], [10, 0], [10, 80]]] - }), [[10, -88.246216], [-10, 88.246216]], 1e-6); - } - }, - "South pole": function(bounds) { - assert.deepEqual(bounds({ - type: "Polygon", - coordinates: [[[-60, -80], [60, -80], [180, -80], [-60, -80]]] - }), [[-180, -90], [180, -80]]); - }, - "ring": function(bounds) { - assert.inDelta(bounds({ - type: "Polygon", - coordinates: [ - [[-60, -80], [60, -80], [180, -80], [-60, -80]], - [[-60, -89], [180, -89], [60, -89], [-60, -89]] - ] - }), [[-180, -89.499961], [180, -80]], 1e-6); - } - }, - "NestedCollection": function(bounds) { - assert.deepEqual(bounds({ - type: "FeatureCollection", - features: [ - { - type: "Feature", - geometry: { - type: "GeometryCollection", - geometries: [ - { - type: "Point", - coordinates: [-120,47] - }, - { - type: "Point", - coordinates: [-119,46] - } - ] - } - } - ] - }), [[-120,46], [-119,47]]); - }, - "null geometries": { - "Feature": function(bounds) { - var b = bounds({type: "Feature", geometry: null}); - assert.isNaN(b[0][0]); - assert.isNaN(b[0][1]); - assert.isNaN(b[1][0]); - assert.isNaN(b[1][1]); - }, - "MultiPoint": function(bounds) { - var b = bounds({type: "MultiPoint", coordinates: []}); - assert.isNaN(b[0][0]); - assert.isNaN(b[0][1]); - assert.isNaN(b[1][0]); - assert.isNaN(b[1][1]); - }, - "MultiLineString": function(bounds) { - var b = bounds({type: "MultiLineString", coordinates: []}); - assert.isNaN(b[0][0]); - assert.isNaN(b[0][1]); - assert.isNaN(b[1][0]); - assert.isNaN(b[1][1]); - }, - "MultiPolygon": function(bounds) { - var b = bounds({type: "MultiPolygon", coordinates: []}); - assert.isNaN(b[0][0]); - assert.isNaN(b[0][1]); - assert.isNaN(b[1][0]); - assert.isNaN(b[1][1]); - } - } - } -}); - -suite.export(module); diff --git a/test/geo/centroid-test.js b/test/geo/centroid-test.js deleted file mode 100644 index 39ce203d8bade1..00000000000000 --- a/test/geo/centroid-test.js +++ /dev/null @@ -1,187 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.centroid"); - -suite.addBatch({ - "centroid": { - topic: load("geo/centroid").expression("d3.geo.centroid"), - - "the centroid of a point is itself": function(centroid) { - assert.inDelta(centroid({type: "Point", coordinates: [0, 0]}), [0, 0], 1e-6); - assert.inDelta(centroid({type: "Point", coordinates: [1, 1]}), [1, 1], 1e-6); - assert.inDelta(centroid({type: "Point", coordinates: [2, 3]}), [2, 3], 1e-6); - assert.inDelta(centroid({type: "Point", coordinates: [-4, -5]}), [-4, -5], 1e-6); - }, - - "the centroid of a set of points is the (spherical) average of its constituent members": function(centroid) { - assert.inDelta(centroid({type: "GeometryCollection", geometries: [{type: "Point", coordinates: [0, 0]}, {type: "Point", coordinates: [1, 2]}]}), [0.499847, 1.000038], 1e-6); - assert.inDelta(centroid({type: "MultiPoint", coordinates: [[0, 0], [1, 2]]}), [0.499847, 1.000038], 1e-6); - assert.inDelta(centroid({type: "MultiPoint", coordinates: [[179, 0], [-179, 0]]}), [180, 0], 1e-6); - }, - - "the centroid of a set of points and their antipodes is ambiguous": function(centroid) { - assert.ok(centroid({type: "MultiPoint", coordinates: [[0, 0], [180, 0]]}).every(isNaN)); - assert.ok(centroid({type: "MultiPoint", coordinates: [[0, 0], [90, 0], [180, 0], [-90, 0]]}).every(isNaN)); - assert.ok(centroid({type: "MultiPoint", coordinates: [[0, 0], [0, 90], [180, 0], [0, -90]]}).every(isNaN)); - }, - - "the centroid of the empty set of points is ambiguous": function(centroid) { - assert.ok(centroid({type: "MultiPoint", coordinates: []}).every(isNaN)); - }, - - "the centroid of a line string is the (spherical) average of its constituent great arc segments": function(centroid) { - assert.inDelta(centroid({type: "LineString", coordinates: [[0, 0], [1, 0]]}), [.5, 0], 1e-6); - assert.inDelta(centroid({type: "LineString", coordinates: [[0, 0], [0, 90]]}), [0, 45], 1e-6); - assert.inDelta(centroid({type: "LineString", coordinates: [[0, 0], [0, 45], [0, 90]]}), [0, 45], 1e-6); - assert.inDelta(centroid({type: "LineString", coordinates: [[-1, -1], [1, 1]]}), [0, 0], 1e-6); - assert.inDelta(centroid({type: "LineString", coordinates: [[-60, -1], [60, 1]]}), [0, 0], 1e-6); - assert.inDelta(centroid({type: "LineString", coordinates: [[179, -1], [-179, 1]]}), [180, 0], 1e-6); - assert.inDelta(centroid({type: "LineString", coordinates: [[-179, 0], [0, 0], [179, 0]]}), [0, 0], 1e-6); - assert.inDelta(centroid({type: "LineString", coordinates: [[-180, -90], [0, 0], [0, 90]]}), [0, 0], 1e-6); - }, - - "the centroid of a great arc from a point to its antipode is ambiguous": function(centroid) { - assert.ok(centroid({type: "LineString", coordinates: [[180, 0], [0, 0]]}).every(isNaN)); - assert.ok(centroid({type: "MultiLineString", coordinates: [[[0, -90], [0, 90]]]}).every(isNaN)); - }, - - "the centroid of a set of line strings is the (spherical) average of its constituent great arc segments": function(centroid) { - assert.inDelta(centroid({type: "MultiLineString", coordinates: [[[0, 0], [0, 2]]]}), [0, 1], 1e-6); - }, - - "a line of zero length is treated as points": function(centroid) { - assert.inDelta(centroid({type: "LineString", coordinates: [[1, 1], [1, 1]]}), [1, 1], 1e-6); - assert.inDelta(centroid({type: "GeometryCollection", geometries: [{type: "Point", coordinates: [0, 0]}, {type: "LineString", coordinates: [[1, 2], [1, 2]]}]}), [0.666534, 1.333408], 1e-6); - }, - - "an empty polygon with non-zero extent is treated as a line": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[1, 1], [2, 1], [3, 1], [2, 1], [1, 1]]]}), [2, 1.000076], 1e-6); - assert.inDelta(centroid({type: "GeometryCollection", geometries: [{type: "Point", coordinates: [0, 0]}, {type: "Polygon", coordinates: [[[1, 2], [1, 2], [1, 2], [1, 2]]]}]}), [0.799907, 1.600077], 1e-6); - }, - - "an empty polygon with zero extent is treated as a point": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[1, 1], [1, 1], [1, 1], [1, 1]]]}), [1, 1], 1e-6); - assert.inDelta(centroid({type: "GeometryCollection", geometries: [{type: "Point", coordinates: [0, 0]}, {type: "Polygon", coordinates: [[[1, 2], [1, 2], [1, 2], [1, 2]]]}]}), [0.799907, 1.600077], 1e-6); - }, - - "the centroid of the equator is ambiguous": function(centroid) { - assert.ok(centroid({type: "LineString", coordinates: [[0, 0], [120, 0], [-120, 0], [0, 0]]}).every(isNaN)); - }, - - "the centroid of a polygon is the (spherical) average of its surface": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[0, -90], [0, 0], [0, 90], [1, 0], [0, -90]]]}), [.5, 0], 1e-6); - assert.inDelta(centroid({type: "Polygon", coordinates: [_.range(-180, 180 + 1 / 2, 1).map(function(x) { return [x, -60]; })]})[1], -90, 1e-6); - assert.inDelta(centroid({type: "Polygon", coordinates: [[[0, -10], [0, 10], [10, 10], [10, -10], [0, -10]]]}), [5, 0], 1e-6); - }, - - "the centroid of a set of polygons is the (spherical) average of its surface": function(centroid) { - var circle = _.geo.circle(); - assert.inDelta(centroid({ - type: "MultiPolygon", - coordinates: [ - circle.angle(45).origin([0, 0])().coordinates, - circle.angle(60).origin([180, 0])().coordinates - ] - }), [180, 0], 1e-6); - }, - - "the centroid of a lune is the (spherical) average of its surface": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[0, -90], [0, 0], [0, 90], [1, 0], [0, -90]]]}), [.5, 0], 1e-6); - }, - - "the centroid of a small circle is its origin": { - "5°": function(centroid) { - assert.inDelta(centroid(_.geo.circle().angle(5).origin([30, 45])()), [30, 45], 1e-6); - }, - "135°": function(centroid) { - assert.inDelta(centroid(_.geo.circle().angle(135).origin([30, 45])()), [30, 45], 1e-6); - }, - "South Pole": function(centroid) { - assert.equal(centroid({type: "Polygon", coordinates: [_.range(-180, 180 + 1 / 2, 1).map(function(x) { return [x, -60]; })]})[1], -90); - }, - "equator": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[0, -10], [0, 10], [10, 10], [10, -10], [0, -10]]]}), [5, 0], 1e-6); - }, - "equator with coincident points": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[0, -10], [0, 10], [0, 10], [10, 10], [10, -10], [0, -10]]]}), [5, 0], 1e-6); - }, - "other": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[-180, 0], [-180, 10], [-179, 10], [-179, 0], [-180, 0]]]}), [-179.5, 4.987448], 1e-6); - }, - "concentric rings": function(centroid) { - var circle = _.geo.circle().origin([0, 45]), - coordinates = circle.angle(60)().coordinates; - coordinates.push(circle.angle(45)().coordinates[0].reverse()); - assert.inDelta(centroid({type: "Polygon", coordinates: coordinates}), [0, 45], 1e-6); - } - }, - - "the centroid of a spherical square on the equator": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[0, -10], [0, 10], [10, 10], [10, -10], [0, -10]]]}), [5, 0], 1e-6); - }, - - "the centroid of a spherical square touching the antimeridian": function(centroid) { - assert.inDelta(centroid({type: "Polygon", coordinates: [[[-180, 0], [-180, 10], [-179, 10], [-179, 0], [-180, 0]]]}), [-179.5, 4.987448], 1e-6); - }, - - "concentric rings": function(centroid) { - var circle = _.geo.circle().origin([0, 45]), - coordinates = circle.angle(60)().coordinates; - coordinates.push(circle.angle(45)().coordinates[0].reverse()); - assert.inDelta(centroid({type: "Polygon", coordinates: coordinates}), [0, 45], 1e-6); - }, - - "the centroid of a sphere is ambiguous": function(centroid) { - assert.ok(centroid({type: "Sphere"}).every(isNaN)); - }, - - "the centroid of a feature is the centroid of its constituent geometry": function(centroid) { - assert.inDelta(centroid({type: "Feature", geometry: {type: "LineString", coordinates: [[1, 1], [1, 1]]}}), [1, 1], 1e-6); - assert.inDelta(centroid({type: "Feature", geometry: {type: "Point", coordinates: [1, 1]}}), [1, 1], 1e-6); - assert.inDelta(centroid({type: "Feature", geometry: {type: "Polygon", coordinates: [[[0, -90], [0, 0], [0, 90], [1, 0], [0, -90]]]}}), [.5, 0], 1e-6); - }, - - "the centroid of a feature collection is the centroid of its constituent geometry": function(centroid) { - assert.inDelta(centroid({type: "FeatureCollection", features: [ - {type: "Feature", geometry: {type: "LineString", coordinates: [[179, 0], [180, 0]]}}, - {type: "Feature", geometry: {type: "Point", coordinates: [0, 0]}} - ]}), [179.5, 0], 1e-6); - }, - - "the centroid of a non-empty line string and a point only considers the line string": function(centroid) { - assert.inDelta(centroid({type: "GeometryCollection", geometries: [ - {type: "LineString", coordinates: [[179, 0], [180, 0]]}, - {type: "Point", coordinates: [0, 0]} - ]}), [179.5, 0], 1e-6); - }, - - "the centroid of a non-empty polygon, a non-empty line string and a point only considers the polygon": function(centroid) { - assert.inDelta(centroid({type: "GeometryCollection", geometries: [ - {type: "Polygon", coordinates: [[[-180, 0], [-180, 1], [-179, 1], [-179, 0], [-180, 0]]]}, - {type: "LineString", coordinates: [[179, 0], [180, 0]]}, - {type: "Point", coordinates: [0, 0]} - ]}), [-179.5, 0.500006], 1e-6); - assert.inDelta(centroid({type: "GeometryCollection", geometries: [ - {type: "Point", coordinates: [0, 0]}, - {type: "LineString", coordinates: [[179, 0], [180, 0]]}, - {type: "Polygon", coordinates: [[[-180, 0], [-180, 1], [-179, 1], [-179, 0], [-180, 0]]]} - ]}), [-179.5, 0.500006], 1e-6); - }, - - "the centroid of the sphere and a point is the point": function(centroid) { - assert.deepEqual(centroid({type: "GeometryCollection", geometries: [ - {type: "Sphere"}, - {type: "Point", coordinates: [0, 0]} - ]}), [0, 0]); - assert.deepEqual(centroid({type: "GeometryCollection", geometries: [ - {type: "Point", coordinates: [0, 0]}, - {type: "Sphere"} - ]}), [0, 0]); - } - } -}); - -suite.export(module); diff --git a/test/geo/circle-test.js b/test/geo/circle-test.js deleted file mode 100644 index f8d6d8abbaa2f0..00000000000000 --- a/test/geo/circle-test.js +++ /dev/null @@ -1,33 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.circle"); - -suite.addBatch({ - "circle": { - topic: load("geo/circle").expression("d3.geo.circle"), - "generates a Polygon": function(circle) { - var o = circle()(); - assert.equal(o.type, "Polygon"); - assert.inDelta(o.coordinates, [[[-78.690067, -90], [-90, -84], [-90, -78], [-90, -72], [-90, -66], [-90, -60], [-90, -54], [-90, -48], [-90, -42], [-90, -36], [-90, -30], [-90, -24], [-90, -18], [-90, -12], [-90, -6], [-90, 0], [-90, 6], [-90, 12], [-90, 18], [-90, 24], [-90, 30], [-90, 36], [-90, 42], [-90, 48], [-90, 54], [-90, 60], [-90, 66], [-90, 72], [-90, 78], [-90, 84], [-89.596672, 90], [90, 84], [90, 78], [90, 72], [90, 66], [90, 60], [90, 54], [90, 48], [90, 42], [90, 36], [90, 30], [90, 24], [90, 18], [90, 12], [90, 6], [90, 0], [90, -6], [90, -12], [90, -18], [90, -24], [90, -30], [90, -36], [90, -42], [90, -48], [90, -54], [90, -60], [90, -66], [90, -72], [90, -78], [90, -84], [89.569782, -90]]], 1e-6); - }, - "origin([0, 90])": function(circle) { - var o = circle().origin([0, 90])(); - assert.equal(o.type, "Polygon"); - assert.inDelta(o.coordinates, [_.range(360, -1, -6).map(function(x) { return [x >= 180 ? x - 360 : x, 0]; })], 1e-6); - }, - "origin([45, 45])": function(circle) { - var o = circle().origin([45, 45]).angle(0)(); - assert.equal(o.type, "Polygon"); - assert.inDelta(o.coordinates[0][0], [45, 45], 1e-6); - }, - "first and last points are coincident": function(circle) { - var o = circle().origin([0, 0]).angle(.02).precision(45)(); - assert.inDelta(o.coordinates[0][0], o.coordinates[0].pop(), 1e-6); - } - } -}); - -suite.export(module); diff --git a/test/geo/clip-extent-test.js b/test/geo/clip-extent-test.js deleted file mode 100644 index f4b75bd11a5010..00000000000000 --- a/test/geo/clip-extent-test.js +++ /dev/null @@ -1,129 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.clipExtent"); - -suite.addBatch({ - "clipExtent": { - topic: load("geo/clip-extent"), - - "extent": { - "defaults to [[0, 0], [960, 500]]": function(d3) { - var clip = d3.geo.clipExtent(); - assert.deepEqual(clip.extent(), [[0, 0], [960, 500]]); - }, - "coerces input values to numbers": function(d3) { - var clip = d3.geo.clipExtent().extent([["1", "2"], ["3", "4"]]), - extent = clip.extent(); - assert.strictEqual(extent[0][0], 1); - assert.strictEqual(extent[0][1], 2); - assert.strictEqual(extent[1][0], 3); - assert.strictEqual(extent[1][1], 4); - }, - "with no arguments, returns the current extent": function(d3) { - var clip = d3.geo.clipExtent(); - assert.deepEqual(clip.extent(), [[0, 0], [960, 500]]); - clip.extent([[1, 2], [3, 4]]); - assert.deepEqual(clip.extent(), [[1, 2], [3, 4]]); - }, - "with an argument, sets the current extent and returns this": function(d3) { - var clip = d3.geo.clipExtent(); - assert.strictEqual(clip.extent([[1, 2], [3, 4]]), clip); - } - }, - - "stream": { - "returns a stream that clips to the current extent": function(d3) { - var clip = d3.geo.clipExtent().extent([[100, 200], [300, 400]]), - stream = clip.stream(testContext); - stream.lineStart(); - stream.point(0, 0); - stream.point(500, 500); - stream.lineEnd(); - assert.deepEqual(testContext.buffer(), [ - {type: "lineStart"}, - {type: "point", x: 200, y: 200}, - {type: "point", x: 300, y: 300}, - {type: "lineEnd"} - ]); - }, - "can clip points": function(d3) { - var clip = d3.geo.clipExtent(), - stream = clip.stream(testContext); - stream.point(-100, -100); - stream.point(0, 0); - stream.point(480, 250); - stream.point(960, 500); - stream.point(1060, 6000); - assert.deepEqual(testContext.buffer(), [ - {type: "point", x: 0, y: 0}, - {type: "point", x: 480, y: 250}, - {type: "point", x: 960, y: 500} - ]); - }, - "can clip lines": function(d3) { - var clip = d3.geo.clipExtent(), - stream = clip.stream(testContext); - stream.lineStart(); - stream.point(-100, -100); - stream.point(1060, 600); - stream.lineEnd(); - assert.deepEqual(testContext.buffer(), [ - {type: "lineStart"}, - {type: "point", x: 66, y: 0}, - {type: "point", x: 894, y: 500}, - {type: "lineEnd"} - ]); - }, - "can clip polygons": function(d3) { - var clip = d3.geo.clipExtent(), - stream = clip.stream(testContext); - stream.polygonStart(); - stream.lineStart(); - stream.point(-100, -100); - stream.point(1060, -100); - stream.point(1060, 600); - stream.point(-100, 600); - stream.lineEnd(); - stream.polygonEnd(); - assert.deepEqual(testContext.buffer(), [ - {type: "polygonStart"}, - {type: "lineStart"}, - {type: "point", x: 0, y: 0}, - {type: "point", x: 960, y: 0}, - {type: "point", x: 960, y: 500}, - {type: "point", x: 0, y: 500}, - {type: "lineEnd"}, - {type: "polygonEnd"} - ]); - }, - "the returned stream is cacheable": function(d3) { - var clip = d3.geo.clipExtent().extent([[100, 200], [300, 400]]), - stream = clip.stream(testContext); - assert.isTrue(stream.valid); - }, - "the returned stream is invalidated when the extent changes": function(d3) { - var clip = d3.geo.clipExtent().extent([[100, 200], [300, 400]]), - stream = clip.stream(testContext); - assert.isTrue(stream.valid); - clip.extent([[0, 0], [960, 500]]); - assert.isFalse(stream.valid); - } - } - } -}); - -suite.export(module); - -var testBuffer = []; - -var testContext = { - point: function(x, y) { testBuffer.push({type: "point", x: Math.round(x), y: Math.round(y)}); }, - lineStart: function() { testBuffer.push({type: "lineStart"}); }, - lineEnd: function() { testBuffer.push({type: "lineEnd"}); }, - polygonStart: function() { testBuffer.push({type: "polygonStart"}); }, - polygonEnd: function() { testBuffer.push({type: "polygonEnd"}); }, - sphere: function() { testBuffer.push({type: "sphere"}); }, - buffer: function() { var result = testBuffer; testBuffer = []; return result; } -}; diff --git a/test/geo/conic-conformal-test.js b/test/geo/conic-conformal-test.js deleted file mode 100644 index c6598c7a475d1c..00000000000000 --- a/test/geo/conic-conformal-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.conicConformal"); - -suite.addBatch({ - "conicConformal": { - topic: load("geo/conic-conformal").expression("d3.geo.conicConformal"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 467.09545781, 31.02694219]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 442.69098342, 47.64115003]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 483.99106549, 103.34182093]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 295.79559728, 507.67642324]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 504.49928992, 42.36530945]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 1446.12378227]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 19.84318514]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.08603028, -1.45982039]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.24872678, -1.34905900]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.02660710, -0.97772119]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -1.22802935, 1.71784282]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.16332860, -1.38423127]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 7.97415855]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -1.53437877]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/conic-equal-area-test.js b/test/geo/conic-equal-area-test.js deleted file mode 100644 index c04bbfc1f2fb43..00000000000000 --- a/test/geo/conic-equal-area-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.conicEqualArea"); - -suite.addBatch({ - "conicEqualArea": { - topic: load("geo/conic-equal-area").expression("d3.geo.conicEqualArea"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 459.42118984, 32.08581547]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 433.22520615, 32.16847746]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 484.01431255, 72.73240059]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 358.03569713, 345.61858148]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 513.32546288, 32.84960593]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 376.37688344]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 31.93472588]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.13719207, -1.45276123]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.31183196, -1.45221015]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.02676208, -1.18178400]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.81309535, 0.63745721]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.22216975, -1.44766929]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 0.84251256]], - "the North Pole": [[ 0.00000000, 90.00000000], [ 0.00000000, -1.46410162]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/conic-equidistant-test.js b/test/geo/conic-equidistant-test.js deleted file mode 100644 index 8725059ffbe9a8..00000000000000 --- a/test/geo/conic-equidistant-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.conicEquidistant"); - -suite.addBatch({ - "conicEquidistant": { - topic: load("geo/conic-equidistant").expression("d3.geo.conicEquidistant"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 462.95768394, 32.17010277]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 437.79988730, 40.06576540]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 484.00316185, 88.80377979]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 341.92988745, 387.20169005]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 509.12411912, 37.80365327]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 472.52947963]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 27.47052037]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.11361544, -1.45219932]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.28133408, -1.39956156]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.02668775, -1.07464147]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.92046742, 0.91467793]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.19416079, -1.41464231]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 1.48352986]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -1.48352986]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/distance-test.js b/test/geo/distance-test.js deleted file mode 100644 index b1000ee0650070..00000000000000 --- a/test/geo/distance-test.js +++ /dev/null @@ -1,20 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("assert"); - -var suite = vows.describe("d3.geo.distance"); - -suite.addBatch({ - "distance": { - topic: load("geo/distance").expression("d3.geo.distance"), - "computes the great-arc distance": function(distance) { - assert.equal(distance([0, 0], [0, 0]), 0); - assert.inDelta(distance([118 + 24 / 60, 33 + 57 / 60], [ 73 + 47 / 60, 40 + 38 / 60]), 3973 / 6371, .5); - }, - "small distance": function(distance) { - assert.isTrue(distance([0, 0], [0, 1e-12]) > 0); - } - } -}); - -suite.export(module); diff --git a/test/geo/equirectangular-test.js b/test/geo/equirectangular-test.js deleted file mode 100644 index de204e1d68120d..00000000000000 --- a/test/geo/equirectangular-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.equirectangular"); - -suite.addBatch({ - "equirectangular": { - topic: load("geo/equirectangular").expression("d3.geo.equirectangular"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 424.98907000, 33.66602637]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 359.13715001, 48.28497214]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 488.21991600, 88.85615375]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 386.73919199, 407.84716262]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 567.40721901, 41.88153382]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 472.52947963]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 27.47052037]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.36673953, -1.44222649]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.80575233, -1.34476685]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.05479944, -1.07429231]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.62173872, 1.05231442]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.58271479, -1.38745644]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 1.48352986]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -1.48352986]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/gnomonic-test.js b/test/geo/gnomonic-test.js deleted file mode 100644 index d5f9aec406739a..00000000000000 --- a/test/geo/gnomonic-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.gnomonic"); - -suite.addBatch({ - "gnomonic": { - topic: load("geo/gnomonic").expression("d3.geo.gnomonic"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 422.38246174, -992.89637169]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 323.76600022, -691.84169545]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 488.22815397, -27.28558622]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 372.51942626, 573.42957804]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 578.85832181, -718.85305295]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 1964.50784541]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000,-1464.50784541]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.38411692, -8.28597600]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -1.04156000, -6.27894464]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.05485436, -1.84857057]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.71653716, 2.15619719]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.65905548, -6.45902035]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 11.43005230]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -11.43005230]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/graticule-test.js b/test/geo/graticule-test.js deleted file mode 100644 index 50e690d85c0f77..00000000000000 --- a/test/geo/graticule-test.js +++ /dev/null @@ -1,188 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.graticule"); - -var ε = 1e-6; - -suite.addBatch({ - "graticule": { - topic: load("geo/graticule").expression("d3.geo.graticule"), - - "extent": { - "sets minorExtent and majorExtent": function(graticule) { - var g = graticule().extent([[-90, -45], [90, 45]]); - assert.deepEqual(g.minorExtent(), [[-90, -45], [90, 45]]); - assert.deepEqual(g.majorExtent(), [[-90, -45], [90, 45]]); - }, - "gets minorExtent": function(graticule) { - var g = graticule().minorExtent([[-90, -45], [90, 45]]); - assert.deepEqual(g.extent(), [[-90, -45], [90, 45]]); - } - }, - - "majorExtent": { - "default longitude ranges from 180°W (inclusive) to 180°E (exclusive)": function(graticule) { - var extent = graticule().majorExtent(); - assert.equal(extent[0][0], -180); - assert.equal(extent[1][0], +180); - }, - "default latitude ranges from 90°S (exclusive) to 90°N (exclusive)": function(graticule) { - var extent = graticule().majorExtent(); - assert.equal(extent[0][1], -90 + ε); - assert.equal(extent[1][1], +90 - ε); - }, - "coerces input values to numbers": function(graticule) { - var g = graticule().majorExtent([["-90", "-45"], ["+90", "+45"]]), - extent = g.majorExtent(); - assert.strictEqual(extent[0][0], -90); - assert.strictEqual(extent[0][1], -45); - assert.strictEqual(extent[1][0], +90); - assert.strictEqual(extent[1][1], +45); - } - }, - - "minorExtent": { - "default longitude ranges from 180°W (inclusive) to 180°E (exclusive)": function(graticule) { - var extent = graticule().minorExtent(); - assert.equal(extent[0][0], -180); - assert.equal(extent[1][0], +180); - }, - "default latitude ranges from 80°S (inclusive) to 80°N (inclusive)": function(graticule) { - var extent = graticule().minorExtent(); - assert.equal(extent[0][1], -80 - ε); - assert.equal(extent[1][1], +80 + ε); - }, - "coerces input values to numbers": function(graticule) { - var g = graticule().minorExtent([["-90", "-45"], ["+90", "+45"]]), - extent = g.minorExtent(); - assert.strictEqual(extent[0][0], -90); - assert.strictEqual(extent[0][1], -45); - assert.strictEqual(extent[1][0], +90); - assert.strictEqual(extent[1][1], +45); - } - }, - - "step": { - "sets minorStep and majorStep": function(graticule) { - var g = graticule().step([22.5, 22.5]); - assert.deepEqual(g.minorStep(), [22.5, 22.5]); - assert.deepEqual(g.majorStep(), [22.5, 22.5]); - }, - "gets minorStep": function(graticule) { - var g = graticule().minorStep([22.5, 22.5]); - assert.deepEqual(g.step(), [22.5, 22.5]); - } - }, - - "minorStep": { - "defaults to 10°, 10°": function(graticule) { - assert.deepEqual(graticule().minorStep(), [10, 10]); - }, - "coerces input values to numbers": function(graticule) { - var g = graticule().minorStep(["45", "11.25"]), - step = g.minorStep(); - assert.strictEqual(step[0], 45); - assert.strictEqual(step[1], 11.25); - } - }, - - "majorStep": { - "defaults to 90°, 360°": function(graticule) { - assert.deepEqual(graticule().majorStep(), [90, 360]); - }, - "coerces input values to numbers": function(graticule) { - var g = graticule().majorStep(["45", "11.25"]), - step = g.majorStep(); - assert.strictEqual(step[0], 45); - assert.strictEqual(step[1], 11.25); - } - }, - - "lines": { - "default longitude ranges from 180°W (inclusive) to 180°E (exclusive)": function(graticule) { - var lines = graticule().lines() - .filter(function(line) { return line.coordinates[0][0] === line.coordinates[1][0]; }) - .sort(function(a, b) { return a.coordinates[0][0] - b.coordinates[0][0]; }); - assert.equal(lines[0].coordinates[0][0], -180); - assert.equal(lines[lines.length - 1].coordinates[0][0], +170); - }, - "default latitude ranges from 90°S (exclusive) to 90°N (exclusive)": function(graticule) { - var lines = graticule().lines() - .filter(function(line) { return line.coordinates[0][1] === line.coordinates[1][1]; }) - .sort(function(a, b) { return a.coordinates[0][1] - b.coordinates[0][1]; }); - assert.equal(lines[0].coordinates[0][1], -80); - assert.equal(lines[lines.length - 1].coordinates[0][1], +80); - }, - "default minor longitude lines extend from 80°S to 80°N": function(graticule) { - var lines = graticule().lines() - .filter(function(line) { return line.coordinates[0][0] === line.coordinates[1][0]; }) - .filter(function(line) { return Math.abs(line.coordinates[0][0] % 90) > ε; }); - lines.forEach(function(line) { - assert.deepEqual(_.extent(line.coordinates, function(p) { return p[1]; }), [-80 - ε, +80 + ε]); - }); - }, - "default major longitude lines extend from 90°S to 90°N": function(graticule) { - var lines = graticule().lines() - .filter(function(line) { return line.coordinates[0][0] === line.coordinates[1][0]; }) - .filter(function(line) { return Math.abs(line.coordinates[0][0] % 90) < ε; }); - lines.forEach(function(line) { - assert.deepEqual(_.extent(line.coordinates, function(p) { return p[1]; }), [-90 + ε, +90 - ε]); - }); - }, - "default latitude lines extend from 180°W to 180°E": function(graticule) { - var lines = graticule().lines() - .filter(function(line) { return line.coordinates[0][1] === line.coordinates[1][1]; }); - lines.forEach(function(line) { - assert.deepEqual(_.extent(line.coordinates, function(p) { return p[0]; }), [-180, +180]); - }); - }, - "returns an array of LineStrings": function(graticule) { - assert.deepEqual(graticule() - .extent([[-90, -45], [90, 45]]) - .step([45, 45]) - .precision(3) - .lines(), [ - {type: "LineString", coordinates: [[-90,-45],[-90,45]]}, // meridian - {type: "LineString", coordinates: [[-45,-45],[-45,45]]}, // meridian - {type: "LineString", coordinates: [[0,-45],[0,45]]}, // meridian - {type: "LineString", coordinates: [[45,-45],[45,45]]}, // meridian - {type: "LineString", coordinates: [[-90,-45],[-87,-45],[-84,-45],[-81,-45],[-78,-45],[-75,-45],[-72,-45],[-69,-45],[-66,-45],[-63,-45],[-60,-45],[-57,-45],[-54,-45],[-51,-45],[-48,-45],[-45,-45],[-42,-45],[-39,-45],[-36,-45],[-33,-45],[-30,-45],[-27,-45],[-24,-45],[-21,-45],[-18,-45],[-15,-45],[-12,-45],[-9,-45],[-6,-45],[-3,-45],[0,-45],[3,-45],[6,-45],[9,-45],[12,-45],[15,-45],[18,-45],[21,-45],[24,-45],[27,-45],[30,-45],[33,-45],[36,-45],[39,-45],[42,-45],[45,-45],[48,-45],[51,-45],[54,-45],[57,-45],[60,-45],[63,-45],[66,-45],[69,-45],[72,-45],[75,-45],[78,-45],[81,-45],[84,-45],[87,-45],[90,-45]]}, - {type: "LineString", coordinates: [[-90,0],[-87,0],[-84,0],[-81,0],[-78,0],[-75,0],[-72,0],[-69,0],[-66,0],[-63,0],[-60,0],[-57,0],[-54,0],[-51,0],[-48,0],[-45,0],[-42,0],[-39,0],[-36,0],[-33,0],[-30,0],[-27,0],[-24,0],[-21,0],[-18,0],[-15,0],[-12,0],[-9,0],[-6,0],[-3,0],[0,0],[3,0],[6,0],[9,0],[12,0],[15,0],[18,0],[21,0],[24,0],[27,0],[30,0],[33,0],[36,0],[39,0],[42,0],[45,0],[48,0],[51,0],[54,0],[57,0],[60,0],[63,0],[66,0],[69,0],[72,0],[75,0],[78,0],[81,0],[84,0],[87,0],[90,0]]} - ]); - } - }, - - "returns a MultiLineString of all lines": function(graticule) { - var g = graticule() - .extent([[-90, -45], [90, 45]]) - .step([45, 45]) - .precision(3); - assert.deepEqual(g(), { - type: "MultiLineString", - coordinates: g.lines().map(function(line) { return line.coordinates; }) - }); - }, - - "outline": { - "returns a Polygon encompassing the major extent": function(graticule) { - assert.deepEqual(graticule() - .majorExtent([[-90, -45], [90, 45]]) - .precision(3) - .outline(), { - type: "Polygon", - coordinates: [[ - [-90,-45],[-90,45], // meridian - [-87,45],[-84,45],[-81,45],[-78,45],[-75,45],[-72,45],[-69,45],[-66,45],[-63,45],[-60,45],[-57,45],[-54,45],[-51,45],[-48,45],[-45,45],[-42,45],[-39,45],[-36,45],[-33,45],[-30,45],[-27,45],[-24,45],[-21,45],[-18,45],[-15,45],[-12,45],[-9,45],[-6,45],[-3,45],[0,45],[3,45],[6,45],[9,45],[12,45],[15,45],[18,45],[21,45],[24,45],[27,45],[30,45],[33,45],[36,45],[39,45],[42,45],[45,45],[48,45],[51,45],[54,45],[57,45],[60,45],[63,45],[66,45],[69,45],[72,45],[75,45],[78,45],[81,45],[84,45],[87,45], - [90,45],[90,-45], // meridian - [87,-45],[84,-45],[81,-45],[78,-45],[75,-45],[72,-45],[69,-45],[66,-45],[63,-45],[60,-45],[57,-45],[54,-45],[51,-45],[48,-45],[45,-45],[42,-45],[39,-45],[36,-45],[33,-45],[30,-45],[27,-45],[24,-45],[21,-45],[18,-45],[15,-45],[12,-45],[9,-45],[6,-45],[3,-45],[0,-45],[-3,-45],[-6,-45],[-9,-45],[-12,-45],[-15,-45],[-18,-45],[-21,-45],[-24,-45],[-27,-45],[-30,-45],[-33,-45],[-36,-45],[-39,-45],[-42,-45],[-45,-45],[-48,-45],[-51,-45],[-54,-45],[-57,-45],[-60,-45],[-63,-45],[-66,-45],[-69,-45],[-72,-45],[-75,-45],[-78,-45],[-81,-45],[-84,-45],[-87,-45],[-90,-45] - ]] - }); - } - } - } -}); - -suite.export(module); diff --git a/test/geo/greatArc-test.js b/test/geo/greatArc-test.js deleted file mode 100644 index efd26966a56dfb..00000000000000 --- a/test/geo/greatArc-test.js +++ /dev/null @@ -1,35 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.greatArc"); - -suite.addBatch({ - "greatArc": { - topic: load("geo/greatArc").expression("d3.geo.greatArc"), - "distance": function(arc) { - var a = arc(); - assert.equal(a.distance({source: [0, 0], target: [0, 0]}), 0); - assert.inDelta(a.distance({ - source: [118 + 24 / 60, 33 + 57 / 60], - target: [ 73 + 47 / 60, 40 + 38 / 60] - }), 3973 / 6371, .5); - }, - "source and target can be set as constants": function(arc) { - var a = arc().source([5, 52]).target([-120, 37]); - assert.inDelta(a().coordinates, [ - [ 5, 52 ], - [-120, 37 ] - ], .5); - }, - "geodesic": function(arc) { - var a = arc(); - assert.inDelta(a({source: [5, 52], target: [-120, 37]}).coordinates, [ - [ 5, 52 ], - [-120, 37 ] - ], .5); - } - } -}); - -suite.export(module); diff --git a/test/geo/interpolate-test.js b/test/geo/interpolate-test.js deleted file mode 100644 index e250ad3b2e458f..00000000000000 --- a/test/geo/interpolate-test.js +++ /dev/null @@ -1,22 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.interpolate"); - -suite.addBatch({ - "interpolate": { - topic: load("geo/interpolate").expression("d3.geo.interpolate"), - "zero distance": function(interpolate) { - assert.deepEqual(interpolate([140.63289, -29.95101], [140.63289, -29.95101])(.5), [140.63289, -29.95101]); - }, - "equator": function(interpolate) { - assert.inDelta(interpolate([10, 0], [20, 0])(.5), [15, 0], 1e-6); - }, - "meridian": function(interpolate) { - assert.inDelta(interpolate([10, -20], [10, 40])(.5), [10, 10], 1e-6); - } - } -}); - -suite.export(module); diff --git a/test/geo/length-test.js b/test/geo/length-test.js deleted file mode 100644 index 8e974618702990..00000000000000 --- a/test/geo/length-test.js +++ /dev/null @@ -1,44 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("assert"); - -var suite = vows.describe("d3.geo.length"); - -var π = Math.PI; - -suite.addBatch({ - "length": { - topic: load("geo/length").expression("d3.geo.length"), - "the length of points are zero": function(length) { - assert.inDelta(length({type: "Point", coordinates: [0, 0]}), 0, 1e-6); - assert.inDelta(length({type: "MultiPoint", coordinates: [[0, 1], [2, 3]]}), 0, 1e-6); - }, - "the length of a line string is the sum of its great arc segments": function(length) { - assert.inDelta(length({type: "LineString", coordinates: [[-45, 0], [45, 0]]}), Math.PI / 2, 1e-6); - assert.inDelta(length({type: "LineString", coordinates: [[-45, 0], [-30, 0], [-15, 0], [0, 0]]}), Math.PI / 4, 1e-6); - assert.inDelta(length({type: "MultiLineString", coordinates: [[[-45, 0], [-30, 0]], [[-15, 0], [0, 0]]]}), Math.PI / 6, 1e-6); - }, - "the length of a polygon is its perimeter": function(length) { - assert.inDelta(length({type: "Polygon", coordinates: [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]]}), 0.157008, 1e-6); - assert.inDelta(length({type: "MultiPolygon", coordinates: [[[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]]]}), 0.157008, 1e-6); - assert.inDelta(length({type: "MultiPolygon", coordinates: [[[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]], [[[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]]]}), 0.209354, 1e-6); - }, - "the length of a polygon is its perimeter, including holes": function(length) { - assert.inDelta(length({type: "Polygon", coordinates: [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]]}), 0.209354, 1e-6); - }, - "the length of a feature collection is the sum of its features": function(length) { - assert.inDelta(length({type: "FeatureCollection", features: [ - {type: "Feature", geometry: {type: "LineString", coordinates: [[-45, 0], [0, 0]]}}, - {type: "Feature", geometry: {type: "LineString", coordinates: [[0, 0], [45, 0]]}} - ]}), Math.PI / 2, 1e-6); - }, - "the length of a geometry collection is the sum of its geometries": function(length) { - assert.inDelta(length({type: "GeometryCollection", geometries: [ - {type: "GeometryCollection", geometries: [{type: "LineString", coordinates: [[-45, 0], [0, 0]]}]}, - {type: "LineString", coordinates: [[0, 0], [45, 0]]} - ]}), Math.PI / 2, 1e-6); - } - } -}); - -suite.export(module); diff --git a/test/geo/mercator-test.js b/test/geo/mercator-test.js deleted file mode 100644 index 2847b59e8d0060..00000000000000 --- a/test/geo/mercator-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.mercator"); - -suite.addBatch({ - "mercator": { - topic: load("geo/mercator").expression("d3.geo.mercator"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 424.98907000, -161.45770791]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 359.13715001, -76.39503103]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 488.21991600, 44.12991498]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 386.73919199, 449.08559401]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 567.40721901, -108.01311493]], - "west antimeridian": [[-180.00000000, 0.00000000], [ 8.76110196, 250.00000000]], - "east antimeridian": [[ 180.00000000, 0.00000000], [ 951.23889804, 250.00000000]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262725, 82.63349099], [ -0.36673953, -2.74305138]], - "San Francisco, CA": [[ -46.16620841, 77.04946502], [ -0.80575234, -2.17596687]], - "Svalbard": [[ 3.13977663, 61.55241514], [ 0.05479944, -1.37246723]], - "Tierra del Fuego": [[ -35.62300462, -60.29317474], [ -0.62173872, 1.32723729]], - "Tokyo": [[ 33.38709813, 79.49539834], [ 0.58271479, -2.38675410]], - "west antimeridian": [[-180.00000000, 0.00000000], [ -3.14159265, 0.00000000]], - "east antimeridian": [[ 180.00000000, 0.00000000], [ 3.14159265, 0.00000000]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/orthographic-test.js b/test/geo/orthographic-test.js deleted file mode 100644 index cfe0c95b2cdf49..00000000000000 --- a/test/geo/orthographic-test.js +++ /dev/null @@ -1,34 +0,0 @@ -var vows = require("vows"), - assert = require("../assert"), - load = require("../load"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.orthographic"); - -suite.addBatch({ - "orthographic": { - topic: load("geo/orthographic").expression("d3.geo.orthographic"), - "default": projectionTestSuite(function(projection) { return projection(); }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 473.10377192, 101.23805835]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 455.75069916, 103.81541376]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 483.91363537, 118.11201123]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 436.70402041, 380.28587327]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 495.04895132, 102.51395975]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 399.42920471]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 100.57079529]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite(function(projection) { return projection().translate([0, 0]).scale(1); }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.04597485, -0.99174628]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.16166201, -0.97456391]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.02609090, -0.87925326]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.28863986, 0.86857249]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.10032634, -0.98324027]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 0.99619470]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -0.99619470]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/path-test.js b/test/geo/path-test.js deleted file mode 100644 index 6cd90cfba3d320..00000000000000 --- a/test/geo/path-test.js +++ /dev/null @@ -1,832 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.path"); - -suite.addBatch({ - "path": { - topic: load("geo/path").expression("d3.geo.path"), - - "with an equirectangular projection": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .precision(0)); - }, - - "renders a point": function(p) { - p({ - type: "Point", - coordinates: [-63, 18] - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 165, y: 160}, - {type: "arc", x: 165, y: 160, r: 4.5} - ]); - }, - - "renders a multipoint": function(p) { - p({ - type: "MultiPoint", - coordinates: [[-63, 18], [-62, 18], [-62, 17]] - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 165, y: 160}, {type: "arc", x: 165, y: 160, r: 4.5}, - {type: "moveTo", x: 170, y: 160}, {type: "arc", x: 170, y: 160, r: 4.5}, - {type: "moveTo", x: 170, y: 165}, {type: "arc", x: 170, y: 165, r: 4.5} - ]); - }, - - "renders a line string": function(p) { - p({ - type: "Feature", - geometry: { - type: "LineString", - coordinates: [[-63, 18], [-62, 18], [-62, 17]] - } - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 165, y: 160}, - {type: "lineTo", x: 170, y: 160}, - {type: "lineTo", x: 170, y: 165} - ]); - }, - - "renders a polygon": function(p) { - p({ - type: "Feature", - geometry: { - type: "Polygon", - coordinates: [[[-63, 18], [-62, 18], [-62, 17], [-63, 18]]] - } - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 165, y: 160}, - {type: "lineTo", x: 170, y: 160}, - {type: "lineTo", x: 170, y: 165}, - {type: "closePath"} - ]); - }, - - "renders a geometry collection": function(p) { - p({ - type: "GeometryCollection", - geometries: [{type: "Point", coordinates: [0, 0]}] - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 480, y: 250}, {type: "arc", x: 480, y: 250, r: 4.5} - ]); - }, - - "renders a feature collection": function(p) { - p({ - type: "FeatureCollection", - features: [{type: "Feature", geometry: {type: "Point", coordinates: [0, 0]}}] - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 480, y: 250}, {type: "arc", x: 480, y: 250, r: 4.5} - ]); - }, - - "longitudes wrap at ±180°": function(p) { - p({type: "Point", coordinates: [180 + 1e-6, 0]}); - assert.deepEqual(testContext.buffer(), [{type: "moveTo", x: -420, y: 250}, {type: "arc", x: -420, y: 250, r: 4.5}]); - }, - - "observes the correct winding order of a tiny polygon": function(p) { - p({type: "Polygon", coordinates: [[ - [-0.06904102953339501, 0.346043661846373], - [-6.725674252975136e-15, 0.3981303360336475], - [-6.742247658534323e-15, -0.08812465346531581], - [-0.17301258217724075, -0.12278150669440671], - [-0.06904102953339501, 0.346043661846373]]]}); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 1); - }, - - "area": { - topic: function(p) { - return p.area; - }, - "of a polygon with no holes": function(area) { - assert.strictEqual(area({type: "Polygon", coordinates: [[[100, 0], [100, 1], [101, 1], [101, 0], [100, 0]]]}), 25); - }, - "of a polygon with holes": function(area) { - assert.strictEqual(area({type: "Polygon", coordinates: [[[100, 0], [100, 1], [101, 1], [101, 0], [100, 0]], [[100.2, .2], [100.8, .2], [100.8, .8], [100.2, .8], [100.2, .2]]]}), 16); - }, - "area of a Sphere": function(area) { - assert.strictEqual(area({type: "Sphere"}), 1620000); - } - }, - - "centroid": { - topic: function(p) { - return p.centroid; - }, - "of a point": function(centroid) { - assert.deepEqual(centroid({type: "Point", coordinates: [0, 0]}), [480, 250]); - }, - "of an empty multipoint": function(centroid) { - assert.ok(centroid({type: "MultiPoint", coordinates: []}).every(isNaN)); - }, - "of a singleton multipoint": function(centroid) { - assert.deepEqual(centroid({type: "MultiPoint", coordinates: [[0, 0]]}), [480, 250]); - }, - "of a multipoint with two points": function(centroid) { - assert.deepEqual(centroid({type: "MultiPoint", coordinates: [[-122, 37], [-74, 40]]}), [-10, 57.5]); - }, - "of an empty linestring": function(centroid) { - assert.ok(centroid({type: "LineString", coordinates: []}).every(isNaN)); - }, - "of a linestring with two points": function(centroid) { - assert.deepEqual(centroid({type: "LineString", coordinates: [[100, 0], [0, 0]]}), [730, 250]); - assert.deepEqual(centroid({type: "LineString", coordinates: [[0, 0], [100, 0], [101, 0]]}), [732.5, 250]); - }, - "of a linestring with two points, one unique": function(centroid) { - assert.deepEqual(centroid({type: "LineString", coordinates: [[-122, 37], [-122, 37]]}), [-130, 65]); - assert.deepEqual(centroid({type: "LineString", coordinates: [[-74, 40], [-74, 40]]}), [110, 50]); - }, - "of a linestring with three points; two unique": function(centroid) { - assert.deepEqual(centroid({type: "LineString", coordinates: [[-122, 37], [-74, 40], [-74, 40]]}), [-10, 57.5]); - }, - "of a linestring with three points": function(centroid) { - assert.inDelta(centroid({type: "LineString", coordinates: [[-122, 37], [-74, 40], [-100, 0]]}), [17.389135, 103.563545], 1e-6); - }, - "of a multilinestring": function(centroid) { - assert.deepEqual(centroid({type: "MultiLineString", coordinates: [[[100, 0], [0, 0]], [[-10, 0], [0, 0]]]}), [705, 250]); - }, - "of a single-ring polygon": function(centroid) { - assert.deepEqual(centroid({type: "Polygon", coordinates: [[[100, 0], [100, 1], [101, 1], [101, 0], [100, 0]]]}), [982.5, 247.5]); - }, - "of a zero-area polygon": function(centroid) { - assert.deepEqual(centroid({type: "Polygon", coordinates: [[[1, 0], [2, 0], [3, 0], [1, 0]]]}), [490, 250]); - }, - "of a polygon with two rings, one with zero area": function(centroid) { - assert.deepEqual(centroid({type: "Polygon", coordinates: [ - [[100, 0], [100, 1], [101, 1], [101, 0], [100, 0]], - [[100.1, 0], [100.2, 0], [100.3, 0], [100.1, 0] - ]]}), [982.5, 247.5]); - }, - "of a polygon with clockwise exterior and anticlockwise interior": function(centroid) { - assert.inDelta(centroid({ - type: "Polygon", - coordinates: [ - [[-2, -2], [2, -2], [2, 2], [-2, 2], [-2, -2]].reverse(), - [[ 0, -1], [1, -1], [1, 1], [ 0, 1], [ 0, -1]] - ] - }), [479.642857, 250], 1e-6); - }, - "of an empty multipolygon": function(centroid) { - assert.ok(centroid({type: "MultiPolygon", coordinates: []}).every(isNaN)); - }, - "of a singleton multipolygon": function(centroid) { - assert.deepEqual(centroid({type: "MultiPolygon", coordinates: [[[[100, 0], [100, 1], [101, 1], [101, 0], [100, 0]]]]}), [982.5, 247.5]); - }, - "of a multipolygon with two polygons": function(centroid) { - assert.deepEqual(centroid({type: "MultiPolygon", coordinates: [ - [[[100, 0], [100, 1], [101, 1], [101, 0], [100, 0]]], - [[[0, 0], [1, 0], [1, -1], [0, -1], [0, 0]]] - ]}), [732.5, 250]); - }, - "of a multipolygon with two polygons, one zero area": function(centroid) { - assert.deepEqual(centroid({type: "MultiPolygon", coordinates: [ - [[[100, 0], [100, 1], [101, 1], [101, 0], [100, 0]]], - [[[0, 0], [1, 0], [2, 0], [0, 0]]] - ]}), [982.5, 247.5]); - }, - "of a geometry collection with a single point": function(centroid) { - assert.deepEqual(centroid({type: "GeometryCollection", geometries: [{type: "Point", coordinates: [0, 0]}]}), [480, 250]); - }, - "of a geometry collection with a point and a linestring": function(centroid) { - assert.deepEqual(centroid({type: "GeometryCollection", geometries: [ - {type: "LineString", coordinates: [[179, 0], [180, 0]]}, - {type: "Point", coordinates: [0, 0]} - ]}), [1377.5, 250]); - }, - "of a geometry collection with a point, linestring and polygon": function(centroid) { - assert.deepEqual(centroid({type: "GeometryCollection", geometries: [ - {type: "Polygon", coordinates: [[[-180, 0], [-180, 1], [-179, 1], [-179, 0], [-180, 0]]]}, - {type: "LineString", coordinates: [[179, 0], [180, 0]]}, - {type: "Point", coordinates: [0, 0]} - ]}), [-417.5, 247.5]); - }, - "of a feature collection with a point": function(centroid) { - assert.deepEqual(centroid({type: "FeatureCollection", features: [{type: "Feature", geometry: {type: "Point", coordinates: [0, 0]}}]}), [480, 250]); - }, - "of a feature collection with a point and a line string": function(centroid) { - assert.deepEqual(centroid({type: "FeatureCollection", features: [ - {type: "Feature", geometry: {type: "LineString", coordinates: [[179, 0], [180, 0]]}}, - {type: "Feature", geometry: {type: "Point", coordinates: [0, 0]}} - ]}), [1377.5, 250]); - }, - "of a feature collection with a point, line string and polygon": function(centroid) { - assert.deepEqual(centroid({type: "FeatureCollection", features: [ - {type: "Feature", geometry: {type: "Polygon", coordinates: [[[-180, 0], [-180, 1], [-179, 1], [-179, 0], [-180, 0]]]}}, - {type: "Feature", geometry: {type: "LineString", coordinates: [[179, 0], [180, 0]]}}, - {type: "Feature", geometry: {type: "Point", coordinates: [0, 0]}} - ]}), [-417.5, 247.5]); - }, - "of a sphere": function(centroid) { - assert.deepEqual(centroid({type: "Sphere"}), [480, 250]); - } - } - }, - - "with a null (identity) projection": { - topic: function(path) { - return path() - .context(testContext) - .projection(null); - }, - "renders a Polygon": function(p) { - p({ - type: "Feature", - geometry: { - type: "Polygon", - coordinates: [[[-63, 18], [-62, 18], [-62, 17], [-63, 18]]] - } - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: -63, y: 18}, - {type: "lineTo", x: -62, y: 18}, - {type: "lineTo", x: -62, y: 17}, - {type: "closePath"} - ]); - } - }, - - "with the default context (null) and an identity projection": { - topic: function(path) { - return path() - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .precision(0)); - }, - "returns null when passed null or undefined": function(p) { - assert.equal(p(null), null); - assert.equal(p(undefined), null); - assert.equal(p(), null); - }, - "returns null with bogus type name": function(p) { - assert.equal(p({ - type: "Feature", - geometry: { - type: "__proto__", - coordinates: [[[-63.03, 18.02], [-63.14, 18.06], [-63.01, 18.07], [-63.03, 18.02]]] - } - }), null); - } - }, - - "with the default context (null) and default projection (albers-usa)": { - topic: function(path) { - return path(); - }, - "area of a polygon": function(p) { - var area = p.area({type: "Polygon", coordinates: [[[-122, 37], [-71, 42], [-80, 25], [-122, 37]]]}); - assert.inDelta(area, 124884.274, 1e-3); - }, - "bounds of a line string": function(p) { - assert.inDelta(p.bounds({type: "LineString", coordinates: [[-122, 37], [-74, 40], [-100, 0]]}), - [[109.378, 189.584], [797.758, 504.660]], 1e-3); - }, - "centroid of a line string": function(p) { - assert.inDelta(p.centroid({type: "LineString", coordinates: [[-122, 37], [-74, 40], [-100, 0]]}), [545.131, 253.860], 1e-3); - } - }, - - "with an equirectangular projection rotated by [180, -248]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([-180, -248]) - .scale(900 / Math.PI) - .precision(0)); - }, - "renders a polygon": function(p) { - p({type: "Polygon", coordinates: [[[-175.03150315031502, 66.57410661866186], [-174.34743474347434, 66.33097912391239], [-174.5994599459946, 67.0603616081608], [-171.86318631863185, 66.90406536153614], [-169.9189918991899, 65.96628788178816], [-170.89108910891088, 65.53213164116411], [-172.54725472547256, 65.42793414341432], [-172.5832583258326, 64.45542416441643], [-172.97929792979298, 64.2470291689169], [-173.91539153915392, 64.28176166816681], [-174.67146714671466, 64.62908666066605], [-176.003600360036, 64.90694665466546], [-176.21962196219621, 65.34110289528951], [-177.22772277227722, 65.51476539153916], [-178.37983798379838, 65.37583539453945], [-178.91989198919893, 65.72316038703869], [-178.7038703870387, 66.10521787878787], [-179.8919891989199, 65.8620903840384], [-179.45994599459945, 65.3932016441644], [-180, 64.97641165316531], [-180, 68.95328281728172], [-177.55175517551754, 68.18916783378336], [-174.95949594959495, 67.19929160516051], [-175.03150315031502, 66.57410661866186]]]}); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 1370, y: 243}]); - } - }, - - "projection": { - "returns the current projection when called with no arguments": function(path) { - var p = path(), projection = _.geo.equirectangular(); - p.projection(projection); - assert.strictEqual(p.projection(), projection); - } - }, - - "pointRadius": { - "returns the current point radius when called with no arguments": function(path) { - var p = path(), radius = function() { return 5; }; - assert.strictEqual(p.pointRadius(), 4.5); - assert.strictEqual(p.pointRadius(radius).pointRadius(), radius); - }, - "coerces point radius to a number": { - "when the radius is specified as a constant": function(path) { - var p = path().projection(null).context(testContext).pointRadius("6"); - assert.strictEqual(p.pointRadius(), 6); - p({type: "Point", coordinates: [0, 0]}); - assert.strictEqual(testContext.buffer().filter(function(d) { return d.type === "arc"; })[0].r, 6); - }, - "when the radius is specified as a function": function(path) { - var p = path().projection(null).context(testContext).pointRadius(function() { return "6"; }); - p({type: "Point", coordinates: [0, 0]}); - assert.strictEqual(testContext.buffer().filter(function(d) { return d.type === "arc"; })[0].r, 6); - } - } - }, - - "with an equirectangular projection clipped to 90°": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90)); - }, - "renders a point": function(p) { - p({ - type: "Point", - coordinates: [-63, 18] - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 165, y: 160}, {type: "arc", x: 165, y: 160, r: 4.5} - ]); - }, - "renders a multipoint": function(p) { - p({ - type: "MultiPoint", - coordinates: [[-63, 18], [-62, 18], [-62, 17]] - }); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 165, y: 160}, {type: "arc", x: 165, y: 160, r: 4.5}, - {type: "moveTo", x: 170, y: 160}, {type: "arc", x: 170, y: 160, r: 4.5}, - {type: "moveTo", x: 170, y: 165}, {type: "arc", x: 170, y: 165, r: 4.5} - ]); - }, - "inserts exterior along clip edge if polygon interior surrounds it": function(p) { - p({type: "Polygon", coordinates: [[[80, -80], [80, 80], [-80, 80], [-80, -80], [80, -80]]]}); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 2); - }, - "inserts exterior along clip edge if polygon exterior surrounds it": function(p) { - p({type: "Polygon", coordinates: [[[100, -80], [-100, -80], [-100, 80], [100, 80], [100, -80]]]}); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 1); - }, - "renders a small circle of 60°": function(p) { - p(_.geo.circle().angle(60)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 276, y: 493}]); - }, - "renders a small circle of 120°": function(p) { - p(_.geo.circle().angle(120)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 87, y: 700}]); - } - }, - - "with an equirectangular projection clipped to 90° and rotated by [-17°, -451°]": { - "renders a polygon": function(path) { - var pole = _.range(-180, 180, 10).map(function(x) { return [x, 70]; }); - pole.push(pole[0]); - path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([-17, -451]) - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90))({type: "Polygon", coordinates: [pole]}); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [ - {type: "moveTo", x: 510, y: 160}, - {type: "moveTo", x: 87, y: 700} - ]); - } - }, - - "with an equirectangular projection clipped to 90° and rotated by [71.03°, 42.37°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([71.03, 42.37]) - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90)); - }, - /* - "grid component": function(path) { - var yStepsBig = _.range(-90, 90, 10); - path({type: "LineString", coordinates: yStepsBig.map(function(y) { return [110, y]; })}); - assert.inDelta(testContext.buffer(), [[ - [109.538009, -90], - [110, -80], - [110, -70], - [110, -60], - [110, -50], - [110, -47.625390] - ]], 1e-6); - }, - */ - "can completely clip a LineString": function(p) { - p({type: "LineString", coordinates: [[90.0, -42.37], [95.0, -42.37], [90.0, -42.37]]}); - assert.deepEqual(testContext.buffer(), []); - }, - "doesn't insert a duplicate point": function(p) { - p({type: "LineString", coordinates: [[0, 0]]}); - assert.deepEqual(testContext.buffer(), [{type: "moveTo", x: 859, y: 187}]); - }, - "renders a visible point": function(p) { - p({type: "Point", coordinates: [0, 0]}); - assert.deepEqual(testContext.buffer(), [{type: "moveTo", x: 859, y: 187}, {type: "arc", x: 859, y: 187, r: 4.5}]); - }, - "does not render an invisible point": function(p) { - p({type: "Point", coordinates: [-180, 0]}); - assert.deepEqual(testContext.buffer(), []); - }, - "renders a multipoint": function(p) { - p({type: "MultiPoint", coordinates: [[0, 0], [-180, 0]]}); - assert.deepEqual(testContext.buffer(), [{type: "moveTo", x: 859, y: 187}, {type: "arc", x: 859, y: 187, r: 4.5}]); - } - }, - - "with an equirectangular projection clipped to 90° and rotated by [-24°, -175.5°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([-24, -175.5]) - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90)); - }, - "renders Antarctica with no gaps": function(p) { - p(antarctica); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 2); - } - }, - - "with an equirectangular projection clipped to 90° and rotated by [90°, 0°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([90, 0]) - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90)); - }, - "renders a small circle of 60°": function(p) { - p(_.geo.circle().angle(60)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 930, y: 550}]); - }, - "renders a small circle of 120°": function(p) { - p(_.geo.circle().angle(120)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 30, y: 550}]); - } - }, - - "with an equirectangular projection clipped to 90° and rotated by [180°, 0°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([180, 0]) - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90)); - }, - "does not render a small circle of 60°": function(p) { - p(_.geo.circle().angle(60)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), []); - }, - "renders a small circle of 120° in two parts": function(p) { - p(_.geo.circle().angle(120)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [ - {type: "moveTo", x: 276, y: 493}, - {type: "moveTo", x: 87, y: 700} - ]); - } - }, - - "with an equirectangular projection clipped to 90° and rotated by [270°, 0°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([270, 0]) - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90)); - }, - "renders a small circle of 60°": function(p) { - p(_.geo.circle().angle(60)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 30, y: -50}]); - }, - "renders a small circle of 120°": function(p) { - p(_.geo.circle().angle(120)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 930, y: -50}]); - } - }, - - "with an equirectangular projection clipped to 90° and rotated by [210°, 1°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([210, 1]) - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90)); - }, - "renders a small circle of 120°": function(p) { - p(_.geo.circle().angle(120)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 930, y: 250}]); - } - }, - - "with an equirectangular projection clipped to 90° and rotated by [-150°, 60°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .rotate([-150, 60]) - .scale(900 / Math.PI) - .precision(0) - .clipAngle(90)); - }, - "renders a small circle of 120°": function(p) { - p(_.geo.circle().angle(120)()); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 30, y: -87}]); - }, - "renders a sphere": function(p) { - p({type: "Sphere"}); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [{type: "moveTo", x: 87, y: 700}]); - } - }, - - "with an equirectangular projection clipped to 170°": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .precision(0) - .clipAngle(170)); - }, - "renders stripes": function(p) { - p(stripes(80, -80)); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [ - {type: "moveTo", x: -420, y: -150}, - {type: "moveTo", x: -420, y: 650}, - {type: "moveTo", x: 1331, y: 259} - ]); - } - }, - - "with an equirectangular projection clipped to 170° and rotated by [0°, -90°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .rotate([0, -90]) - .precision(0) - .clipAngle(170)); - }, - "renders stripes": function(p) { - p(stripes(80, -80)); - assert.deepEqual(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }), [ - {type: "moveTo", x: 480, y: 200}, - {type: "moveTo", x: 1350, y: 210} - ]); - } - }, - - "with an equirectangular projection clipped to 30°": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .precision(0) - .clipAngle(30)); - }, - "clips lines with two invisible endpoints and visible middle": function(p) { - p({type: "LineString", coordinates: [[-45, 0], [45, 0]]}); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 330, y: 250}, - {type: "lineTo", x: 630, y: 250} - ]); - } - }, - - "with an equirectangular projection clipped to 150°": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .precision(0) - .clipAngle(150)); - }, - "clips lines with two visible endpoints and invisible middle": function(p) { - p({type: "LineString", coordinates: [[135, 0], [-135, 0]]}); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 1155, y: 250}, - {type: "lineTo", x: 1230, y: 250}, - {type: "moveTo", x: -270, y: 250}, - {type: "lineTo", x: -195, y: 250} - ]); - } - }, - - "with an equirectangular projection rotated by [98°, 0°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .rotate([98, 0]) - .precision(0)); - }, - "renders Keweenaw, a small U.S. county": function(p) { - p({ - type: "Polygon", - coordinates: [[[-88.23013, 47.198326], [-88.514931, 47.285957], [-88.383484, 47.285957], [-88.23013, 47.198326]]] - }); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 1); - }, - "renders Accomack, a small U.S. county": function(p) { - p({ - type: "MultiPolygon", - coordinates: [ - [[[-75.397659, 38.013497], [-75.244304, 38.029928], [-75.666029, 37.465803], [-75.939876, 37.547957], [-75.671506, 37.95325], [-75.622213, 37.991589], [-75.397659, 38.013497]]], - [[[-76.016553, 37.95325], [-76.043938, 37.95325], [-75.994645, 37.95325], [-76.016553, 37.95325]]] - ] - }); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 2); - }, - "renders Hopewell, a small U.S. county": function(p) { - p({ - type: "Polygon", - coordinates: [[[-77.298157, 37.312448], [-77.298157, 37.312448], [-77.336496, 37.312448], [-77.281726, 37.312448], [-77.298157, 37.312448]]] - }); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 1); - } - }, - - "with an equirectangular projection rotated by [330°, 232°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .rotate([330, 232]) - .precision(0)); - }, - "renders degenerate points for a small circle of 30°": function(p) { - p(_.geo.circle().angle(30)()); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 2); - } - }, - - "with an equirectangular projection rotated by [34.5°, 90°]": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .rotate([34.5, 90]) - .precision(0)); - }, - "observes proper clip point ordering for lines": function(p) { - var line = _.range(-90, 180, 10).map(function(x) { return [x, 20]; }) - .concat(_.range(170, -100, -10).map(function(x) { return [x, 0]; })) - .concat([[-90, 20]]); - p({type: "Polygon", coordinates: [line]}); - assert.equal(testContext.buffer().filter(function(d) { return d.type === "moveTo"; }).length, 3); - } - }, - - "with an equirectangular projection with the viewport clipped to 960×500": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.equirectangular() - .scale(900 / Math.PI) - .clipExtent([[0, 0], [960, 500]]) - .precision(0)); - }, - "doesn't generate a redundant closing point": function(p) { - p({type: "Polygon", coordinates: [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]}); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 480, y: 250}, - {type: "lineTo", x: 480, y: 245}, - {type: "lineTo", x: 485, y: 245}, - {type: "lineTo", x: 485, y: 250}, - {type: "closePath"} - ]); - } - }, - - "with a stereographic projection and adaptive resampling": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.stereographic() - .precision(1)); - }, - "correctly resamples points on antimeridian": function(p) { - p({type: "LineString", coordinates: [[0, 90], [90, 0]]}); - assert.deepEqual(testContext.buffer(), [ - {type: "moveTo", x: 480, y: 100}, - {type: "lineTo", x: 509, y: 103}, - {type: "lineTo", x: 537, y: 111}, - {type: "lineTo", x: 563, y: 125}, - {type: "lineTo", x: 586, y: 144}, - {type: "lineTo", x: 605, y: 167}, - {type: "lineTo", x: 619, y: 193}, - {type: "lineTo", x: 627, y: 221}, - {type: "lineTo", x: 630, y: 250} - ]); - } - }, - - "with an Albers projection and adaptive resampling": { - "correctly resamples near the poles": function(path) { - var p = path() - .context(testContext) - .projection(_.geo.albers() - .scale(140) - .rotate([0, 0]) - .precision(1)); - p({type: "LineString", coordinates: [[0, 88], [180, 89]]}); - assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1); - p({type: "LineString", coordinates: [[180, 90], [1, 89.5]]}); - assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1); - }, - "rotate([11.5, 285])": function(path) { - var p = path() - .context(testContext) - .projection(_.geo.albers() - .scale(140) - .rotate([11.5, 285]) - .precision(1)); - p({type: "LineString", coordinates: [[170, 20], [170, 0]]}); - assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1); - }, - "wavy projection": function(path) { - var p = path() - .context(testContext) - .projection(_.geo.projection(function(λ, φ) { - return [λ, Math.sin(λ * 4)]; - }) - .scale(140) - .precision(1)); - p({type: "LineString", coordinates: [[-45, 0], [45, 0]]}); - assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1); - } - }, - - "with an Albers projection rotated by [11.5°, 285°] and adaptive resampling": { - topic: function(path) { - return path() - .context(testContext) - .projection(_.geo.albers() - .scale(140) - .rotate([11.5, 285]) - .precision(1)); - }, - "correctly resamples near the poles": function(p) { - p({type: "LineString", coordinates: [[170, 20], [170, 0]]}); - assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1); - } - } - } -}); - -var testBuffer = []; - -var testContext = { - arc: function(x, y, r, a0, a1) { testBuffer.push({type: "arc", x: Math.round(x), y: Math.round(y), r: r}); }, - moveTo: function(x, y) { testBuffer.push({type: "moveTo", x: Math.round(x), y: Math.round(y)}); }, - lineTo: function(x, y) { testBuffer.push({type: "lineTo", x: Math.round(x), y: Math.round(y)}); }, - closePath: function() { testBuffer.push({type: "closePath"}); }, - buffer: function() { var result = testBuffer; testBuffer = []; return result; } -}; - -function stripes(a, b) { - return {type: "Polygon", coordinates: [a, b].map(function(d, i) { - var stripe = _.range(-180, 180, 1).map(function(x) { return [x, d]; }); - stripe.push(stripe[0]); - return i ? stripe.reverse() : stripe; - })}; -} - -var antarctica = {type: "Polygon", coordinates: [[[-58.61414,-64.15246],[-59.04507,-64.36800],[-59.78934,-64.21122],[-60.61192,-64.30920],[-61.29741,-64.54432],[-62.02210,-64.79909],[-62.51176,-65.09302],[-62.64885,-65.48494],[-62.59012,-65.85721],[-62.12007,-66.19032],[-62.80556,-66.42550],[-63.74569,-66.50384],[-64.29410,-66.83700],[-64.88169,-67.15047],[-65.50842,-67.58161],[-65.66508,-67.95388],[-65.31254,-68.36533],[-64.78371,-68.67890],[-63.96110,-68.91398],[-63.19729,-69.22755],[-62.78595,-69.61941],[-62.57051,-69.99174],[-62.27673,-70.38366],[-61.80666,-70.71676],[-61.51290,-71.08904],[-61.37580,-72.01007],[-61.08197,-72.38235],[-61.00366,-72.77426],[-60.69026,-73.16617],[-60.82736,-73.69524],[-61.37580,-74.10674],[-61.96336,-74.43984],[-63.29520,-74.57699],[-63.74569,-74.92974],[-64.35283,-75.26284],[-65.86098,-75.63512],[-67.19281,-75.79191],[-68.44628,-76.00745],[-69.79772,-76.22299],[-70.60072,-76.63449],[-72.20677,-76.67366],[-73.96953,-76.63449],[-75.55597,-76.71288],[-77.24037,-76.71288],[-76.92697,-77.10480],[-75.39929,-77.28106],[-74.28287,-77.55542],[-73.65611,-77.90811],[-74.77253,-78.22163],[-76.49610,-78.12365],[-77.92585,-78.37841],[-77.98466,-78.78991],[-78.02378,-79.18183],[-76.84863,-79.51493],[-76.63322,-79.88721],[-75.36009,-80.25954],[-73.24485,-80.41633],[-71.44294,-80.69062],[-70.01316,-81.00415],[-68.19164,-81.31767],[-65.70427,-81.47445],[-63.25603,-81.74875],[-61.55202,-82.04269],[-59.69141,-82.37585],[-58.71212,-82.84610],[-58.22248,-83.21843],[-57.00811,-82.86569],[-55.36289,-82.57175],[-53.61977,-82.25823],[-51.54364,-82.00352],[-49.76134,-81.72917],[-47.27393,-81.70958],[-44.82570,-81.84673],[-42.80836,-82.08191],[-42.16202,-81.65082],[-40.77143,-81.35689],[-38.24481,-81.33730],[-36.26666,-81.12171],[-34.38639,-80.90617],[-32.31029,-80.76902],[-30.09709,-80.59265],[-28.54980,-80.33793],[-29.25490,-79.98519],[-29.68580,-79.63250],[-29.68580,-79.26022],[-31.62480,-79.29939],[-33.68132,-79.45613],[-35.63991,-79.45613],[-35.91410,-79.08385],[-35.77700,-78.33924],[-35.32654,-78.12365],[-33.89676,-77.88852],[-32.21236,-77.65345],[-30.99805,-77.35951],[-29.78373,-77.06557],[-28.88277,-76.67366],[-27.51175,-76.49734],[-26.16033,-76.36014],[-25.47482,-76.28180],[-23.92755,-76.24258],[-22.45859,-76.10543],[-21.22469,-75.90947],[-20.01037,-75.67434],[-18.91354,-75.43921],[-17.52298,-75.12569],[-16.64158,-74.79253],[-15.70149,-74.49860],[-15.40771,-74.10674],[-16.46532,-73.87161],[-16.11278,-73.46011],[-15.44685,-73.14654],[-14.40880,-72.95058],[-13.31197,-72.71545],[-12.29350,-72.40193],[-11.51006,-72.01007],[-11.02043,-71.53976],[-10.29577,-71.26541],[-9.10101,-71.32422],[-8.61138,-71.65733],[-7.41662,-71.69650],[-7.37745,-71.32422],[-6.86823,-70.93231],[-5.79098,-71.03028],[-5.53637,-71.40261],[-4.34166,-71.46137],[-3.04898,-71.28505],[-1.79549,-71.16743],[-0.65948,-71.22624],[-0.22863,-71.63774],[0.86819,-71.30463],[1.88668,-71.12826],[3.02263,-70.99111],[4.13905,-70.85391],[5.15754,-70.61878],[6.27391,-70.46205],[7.13571,-70.24651],[7.74286,-69.89376],[8.48711,-70.14853],[9.52513,-70.01133],[10.24984,-70.48163],[10.81782,-70.83433],[11.95382,-70.63837],[12.40428,-70.24651],[13.42277,-69.97216],[14.73499,-70.03091],[15.12675,-70.40324],[15.94934,-70.03091],[17.02658,-69.91335],[18.20171,-69.87418],[19.25937,-69.89376],[20.37573,-70.01133],[21.45298,-70.07014],[21.92303,-70.40324],[22.56940,-70.69718],[23.66618,-70.52081],[24.84135,-70.48163],[25.97730,-70.48163],[27.09372,-70.46205],[28.09258,-70.32485],[29.15024,-70.20728],[30.03158,-69.93293],[30.97173,-69.75661],[31.99017,-69.65864],[32.75405,-69.38429],[33.30244,-68.83564],[33.87041,-68.50258],[34.90849,-68.65927],[35.30020,-69.01201],[36.16201,-69.24714],[37.20003,-69.16874],[37.90510,-69.52144],[38.64940,-69.77620],[39.66789,-69.54107],[40.02043,-69.10994],[40.92135,-68.93362],[41.95943,-68.60051],[42.93870,-68.46331],[44.11387,-68.26740],[44.89729,-68.05186],[45.71992,-67.81673],[46.50334,-67.60119],[47.44344,-67.71875],[48.34441,-67.36606],[48.99073,-67.09171],[49.93088,-67.11130],[50.75347,-66.87617],[50.94932,-66.52348],[51.79154,-66.24913],[52.61413,-66.05317],[53.61303,-65.89639],[54.53355,-65.81804],[55.41494,-65.87680],[56.35504,-65.97478],[57.15809,-66.24913],[57.25596,-66.68021],[58.13736,-67.01332],[58.74450,-67.28767],[59.93931,-67.40523],[60.60522,-67.67958],[61.42780,-67.95388],[62.38748,-68.01269],[63.19048,-67.81673],[64.05234,-67.40523],[64.99244,-67.62072],[65.97171,-67.73834],[66.91186,-67.85590],[67.89113,-67.93430],[68.89003,-67.93430],[69.71262,-68.97279],[69.67345,-69.22755],[69.55594,-69.67822],[68.59625,-69.93293],[67.81273,-70.30526],[67.94988,-70.69718],[69.06630,-70.67754],[68.92915,-71.06945],[68.41998,-71.44178],[67.94988,-71.85328],[68.71376,-72.16680],[69.86930,-72.26478],[71.02489,-72.08841],[71.57328,-71.69650],[71.90628,-71.32422],[72.45462,-71.01070],[73.08141,-70.71676],[73.33602,-70.36402],[73.86487,-69.87418],[74.49155,-69.77620],[75.62755,-69.73703],[76.62646,-69.61941],[77.64490,-69.46268],[78.13453,-69.07076],[78.42837,-68.69844],[79.11385,-68.32621],[80.09312,-68.07150],[80.93534,-67.87554],[81.48379,-67.54238],[82.05176,-67.36606],[82.77642,-67.20928],[83.77533,-67.30726],[84.67620,-67.20928],[85.65552,-67.09171],[86.75235,-67.15047],[87.47701,-66.87617],[87.98628,-66.20991],[88.35841,-66.48426],[88.82840,-66.95456],[89.67063,-67.15047],[90.63036,-67.22886],[91.59009,-67.11130],[92.60853,-67.18969],[93.54863,-67.20928],[94.17541,-67.11130],[95.01759,-67.17011],[95.78147,-67.38565],[96.68239,-67.24850],[97.75964,-67.24850],[98.68020,-67.11130],[99.71818,-67.24850],[100.38418,-66.91534],[100.89335,-66.58223],[101.57889,-66.30788],[102.83241,-65.56328],[103.47867,-65.70048],[104.24255,-65.97478],[104.90845,-66.32752],[106.18156,-66.93493],[107.16088,-66.95456],[108.08139,-66.95456],[109.15863,-66.83700],[110.23583,-66.69980],[111.05847,-66.42550],[111.74395,-66.13156],[112.86037,-66.09234],[113.60467,-65.87680],[114.38808,-66.07276],[114.89730,-66.38628],[115.60238,-66.69980],[116.69916,-66.66063],[117.38470,-66.91534],[118.57946,-67.17011],[119.83292,-67.26808],[120.87099,-67.18969],[121.65441,-66.87617],[122.32036,-66.56265],[123.22129,-66.48426],[124.12227,-66.62146],[125.16024,-66.71938],[126.10039,-66.56265],[127.00142,-66.56265],[127.88276,-66.66063],[128.80328,-66.75861],[129.70425,-66.58223],[130.78145,-66.42550],[131.79994,-66.38628],[132.93589,-66.38628],[133.85646,-66.28830],[134.75738,-66.20996],[135.03158,-65.72007],[135.07075,-65.30857],[135.69748,-65.58286],[135.87380,-66.03359],[136.20670,-66.44509],[136.61804,-66.77819],[137.46027,-66.95456],[138.59622,-66.89576],[139.90844,-66.87617],[140.80942,-66.81736],[142.12169,-66.81736],[143.06184,-66.79778],[144.37406,-66.83700],[145.49042,-66.91534],[146.19555,-67.22886],[145.99969,-67.60119],[146.64606,-67.89513],[147.72326,-68.13025],[148.83962,-68.38502],[150.13231,-68.56129],[151.48370,-68.71812],[152.50224,-68.87481],[153.63819,-68.89450],[154.28456,-68.56129],[155.16585,-68.83564],[155.92979,-69.14921],[156.81113,-69.38429],[158.02552,-69.48226],[159.18101,-69.59983],[159.67069,-69.99174],[160.80665,-70.22687],[161.57047,-70.57961],[162.68689,-70.73635],[163.84243,-70.71676],[164.91968,-70.77552],[166.11443,-70.75593],[167.30909,-70.83433],[168.42561,-70.97148],[169.46358,-71.20666],[170.50166,-71.40261],[171.20679,-71.69650],[171.08922,-72.08841],[170.56042,-72.44115],[170.10995,-72.89182],[169.75736,-73.24452],[169.28732,-73.65601],[167.97510,-73.81280],[167.38748,-74.16549],[166.09480,-74.38104],[165.64439,-74.77295],[164.95885,-75.14528],[164.23419,-75.45880],[163.82279,-75.87030],[163.56823,-76.24258],[163.47026,-76.69330],[163.48989,-77.06557],[164.05787,-77.45744],[164.27336,-77.82977],[164.74346,-78.18251],[166.60412,-78.31961],[166.99578,-78.75074],[165.19387,-78.90748],[163.66621,-79.12302],[161.76638,-79.16224],[160.92416,-79.73048],[160.74789,-80.20073],[160.31696,-80.57306],[159.78821,-80.94539],[161.12001,-81.27850],[161.62928,-81.69000],[162.49099,-82.06227],[163.70533,-82.39543],[165.09594,-82.70895],[166.60412,-83.02247],[168.89566,-83.33599],[169.40478,-83.82589],[172.28393,-84.04143],[172.47704,-84.11791],[173.22408,-84.41371],[175.98567,-84.15899],[178.27721,-84.47251],[180.00000,-84.71338],[180.00000,-90.0],[-180.0,-90.0],[-180.0,-84.71338],[-179.94249,-84.72144],[-179.05867,-84.13941],[-177.25677,-84.45293],[-177.14080,-84.41794],[-176.86199,-84.33381],[-176.52395,-84.23181],[-176.23030,-84.14320],[-176.08467,-84.09925],[-175.93410,-84.10159],[-175.82988,-84.11791],[-174.38250,-84.53432],[-173.11655,-84.11791],[-172.88910,-84.06101],[-169.95122,-83.88464],[-168.99998,-84.11791],[-168.53019,-84.23739],[-167.02209,-84.57049],[-164.18214,-84.82520],[-161.92977,-85.13873],[-158.07137,-85.37391],[-155.19225,-85.09955],[-150.94209,-85.29551],[-148.53307,-85.60903],[-145.88891,-85.31510],[-143.10771,-85.04075],[-142.89227,-84.57049],[-146.82906,-84.53127],[-150.06073,-84.29614],[-150.90292,-83.90423],[-153.58620,-83.68868],[-153.40990,-83.23801],[-153.03775,-82.82652],[-152.66563,-82.45419],[-152.86151,-82.04269],[-154.52629,-81.76839],[-155.29017,-81.41565],[-156.83744,-81.10212],[-154.40878,-81.16093],[-152.09766,-81.00415],[-150.64829,-81.33730],[-148.86599,-81.04337],[-147.22074,-80.67104],[-146.41774,-80.33793],[-146.77028,-79.92643],[-148.06294,-79.65208],[-149.53190,-79.35820],[-151.58841,-79.29939],[-153.39032,-79.16224],[-155.32937,-79.06426],[-155.97566,-78.69193],[-157.26830,-78.37841],[-158.05176,-78.02567],[-158.36513,-76.88920],[-157.87547,-76.98723],[-156.97457,-77.30075],[-155.32937,-77.20272],[-153.74283,-77.06557],[-152.92024,-77.49666],[-151.33378,-77.39873],[-150.00194,-77.18314],[-148.74848,-76.90884],[-147.61248,-76.57573],[-146.10440,-76.47775],[-146.14352,-76.10543],[-146.49609,-75.73315],[-146.20230,-75.38041],[-144.90962,-75.20403],[-144.32203,-75.53719],[-142.79435,-75.34123],[-141.63876,-75.08647],[-140.20900,-75.06688],[-138.85759,-74.96891],[-137.50619,-74.73378],[-136.42890,-74.51824],[-135.21458,-74.30269],[-134.43119,-74.36145],[-133.74565,-74.43984],[-132.25716,-74.30269],[-130.92531,-74.47901],[-129.55428,-74.45943],[-128.24203,-74.32228],[-126.89062,-74.42026],[-125.40208,-74.51824],[-124.01149,-74.47901],[-122.56215,-74.49860],[-121.07361,-74.51824],[-119.70255,-74.47901],[-118.68414,-74.18508],[-117.46980,-74.02834],[-116.21631,-74.24389],[-115.02155,-74.06751],[-113.94433,-73.71482],[-113.29798,-74.02834],[-112.94545,-74.38104],[-112.29908,-74.71419],[-111.26105,-74.42026],[-110.06632,-74.79253],[-108.71490,-74.91010],[-107.55934,-75.18445],[-106.14914,-75.12569],[-104.87607,-74.94932],[-103.36794,-74.98849],[-102.01650,-75.12569],[-100.64553,-75.30201],[-100.11669,-74.87093],[-100.76304,-74.53782],[-101.25270,-74.18508],[-102.54533,-74.10674],[-103.11331,-73.73441],[-103.32875,-73.36208],[-103.68128,-72.61753],[-102.91748,-72.75467],[-101.60523,-72.81343],[-100.31252,-72.75467],[-99.13737,-72.91141],[-98.11888,-73.20534],[-97.68803,-73.55804],[-96.33659,-73.61684],[-95.04396,-73.47969],[-93.67290,-73.28374],[-92.43900,-73.16617],[-91.42056,-73.40130],[-90.08873,-73.32291],[-89.22695,-72.55872],[-88.42395,-73.00939],[-87.26833,-73.18576],[-86.01482,-73.08778],[-85.19223,-73.47969],[-83.87999,-73.51887],[-82.66564,-73.63643],[-81.47091,-73.85197],[-80.68744,-73.47969],[-80.29579,-73.12695],[-79.29688,-73.51887],[-77.92585,-73.42089],[-76.90736,-73.63643],[-76.22187,-73.96954],[-74.89004,-73.87161],[-73.85202,-73.65601],[-72.83353,-73.40130],[-71.61921,-73.26415],[-70.20904,-73.14654],[-68.93591,-73.00939],[-67.95662,-72.79385],[-67.36906,-72.48032],[-67.13403,-72.04924],[-67.25154,-71.63774],[-67.56494,-71.24583],[-67.91747,-70.85391],[-68.23084,-70.46205],[-68.48545,-70.10931],[-68.54420,-69.71739],[-68.44628,-69.32553],[-67.97623,-68.95320],[-67.58449,-68.54170],[-67.42784,-68.14984],[-67.62367,-67.71875],[-67.74118,-67.32684],[-67.25154,-66.87617],[-66.70318,-66.58223],[-66.05681,-66.20996],[-65.37132,-65.89639],[-64.56827,-65.60250],[-64.17654,-65.17142],[-63.62815,-64.89707],[-63.00139,-64.64230],[-62.04168,-64.58355],[-61.41492,-64.27003],[-60.70985,-64.07407],[-59.88726,-63.95651],[-59.16258,-63.70174],[-58.59455,-63.38822],[-57.81114,-63.27066],[-57.22358,-63.52542],[-57.59572,-63.85853],[-58.61414,-64.15246]]]}; - -suite.export(module); diff --git a/test/geo/point-in-polygon-mock.js b/test/geo/point-in-polygon-mock.js deleted file mode 100644 index c32a5a08d1ac68..00000000000000 --- a/test/geo/point-in-polygon-mock.js +++ /dev/null @@ -1,18 +0,0 @@ -import "../../src/geo/point-in-polygon"; -import "../../src/math/trigonometry"; - -d3.geo.pointInPolygon = function(polygon) { - polygon = polygon.map(function(ring) { - ring = ring.map(pointRadians); - ring.pop(); - return ring; - }); - - return function(point) { - return d3_geo_pointInPolygon(pointRadians(point), polygon); - }; - - function pointRadians(point) { - return [point[0] * d3_radians, point[1] * d3_radians]; - } -}; diff --git a/test/geo/point-in-polygon-test.js b/test/geo/point-in-polygon-test.js deleted file mode 100644 index 02687b09411f24..00000000000000 --- a/test/geo/point-in-polygon-test.js +++ /dev/null @@ -1,382 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.pointInPolygon"); - -suite.addBatch({ - "d3.geo.pointInPolygon": { - topic: load("../test/geo/point-in-polygon-mock").expression("d3.geo.pointInPolygon"), - "empty": function(pointInPolygon) { - assert.ok(!pointInPolygon([])([0, 0])); - }, - "simple": { - topic: function(pointInPolygon) { - return pointInPolygon([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([.1, 2])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([.1, .1])); - } - }, - "small circle": { - topic: function(pointInPolygon) { - return pointInPolygon(_.geo.circle().angle(60)().coordinates); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([-180, 0])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([1, 1])); - } - }, - "South pole": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[-60, -80], [60, -80], [180, -80], [-60, -80]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 0])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, -85])); - } - }, - "North pole": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[60, 80], [-60, 80], [-180, 80], [60, 80]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 0])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 85])); - } - }, - "larger than hemisphere": { - "near [0°, 0°]": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([.1, .1])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([2, .1])); - } - }, - "South pole": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[-60, 80], [60, 80], [180, 80], [-60, 80]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 85])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 0])); - } - }, - "North pole": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[60, -80], [-60, -80], [-180, -80], [60, -80]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, -85])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 0])); - } - }, - "circle with radius 120°": { - topic: function(pointInPolygon) { - return pointInPolygon(_.geo.circle().angle(120)().coordinates); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([-180, 0])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([-90, 0])); - } - }, - "narrow strip hole, length 340°": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[-170, -1], [0, -1], [170, -1], [170, 1], [0, 1], [-170, 1], [-170, -1]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 0])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 20])); - } - }, - "narrow equatorial hole": { - topic: function(pointInPolygon) { - var circle = _.geo.circle().origin([0, -90]); - return pointInPolygon([ - circle.angle(90 - .01)().coordinates[0], - circle.angle(90 + .01)().coordinates[0].reverse() - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 0])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, -90])); - } - }, - "narrow equatorial strip": { - topic: function(pointInPolygon) { - var circle = _.geo.circle().origin([0, -90]); - return pointInPolygon([ - circle.angle(90 + .01)().coordinates[0], - circle.angle(90 - .01)().coordinates[0].reverse() - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, -90])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 0])); - } - } - }, - "ring": { - "near [0°, 0°]": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], - [[.4, .4], [.6, .4], [.6, .6], [.4, .6], [.4, .4]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([.5, .5])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([.1, .5])); - } - }, - "equatorial": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[0, -10], [-120, -10], [120, -10], [0, -10]], - [[0, 10], [120, 10], [-120, 10], [0, 10]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 20])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 0])); - } - }, - "excluding both poles": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[10, 10], [-10, 10], [-10, -10], [10, -10], [10, 10]].reverse(), - [[170, 10], [170, -10], [-170, -10], [-170, 10], [170, 10]].reverse() - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 90])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 0])); - } - }, - "containing both poles": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[10, 10], [-10, 10], [-10, -10], [10, -10], [10, 10]], - [[170, 10], [170, -10], [-170, -10], [-170, 10], [170, 10]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 0])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 20])); - } - }, - "containing the South pole": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[10, 10], [-10, 10], [-10, -10], [10, -10], [10, 10]], - [[0, 80], [120, 80], [-120, 80], [0, 80]] - ]); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 90])); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, -90])); - } - }, - "containing the North pole": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[10, 10], [-10, 10], [-10, -10], [10, -10], [10, 10]].reverse(), - [[0, 80], [120, 80], [-120, 80], [0, 80]].reverse() - ]); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 90])); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, -90])); - } - } - }, - "self-intersecting": { - "near [0°, 0°]": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[0, 0], [1, 0], [1, 3], [3, 3], [3, 1], [0, 1], [0, 0]] - ]); - }, - "inside": { - "counter-clockwise region": function(pointInPolygon) { - assert.ok(pointInPolygon([.5, .5])); - }, - "clockwise region": function(pointInPolygon) { - assert.ok(pointInPolygon([2, 2])); - } - }, - "outside": { - "counter-clockwise region": function(pointInPolygon) { - assert.ok(!pointInPolygon([15, .5])); - }, - "clockwise region": function(pointInPolygon) { - assert.ok(!pointInPolygon([12, 2])); - } - } - }, - "near the South pole": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[-10, -80], [120, -80], [-120, -80], [10, -85], [10, -75], [-10, -75], [-10, -80]] - ]); - }, - "inside": { - "counter-clockwise region": function(pointInPolygon) { - assert.ok(pointInPolygon([0, -76])); - }, - "clockwise region": function(pointInPolygon) { - assert.ok(pointInPolygon([0, -89])); - } - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 0])); - } - }, - "near the North pole": { - topic: function(pointInPolygon) { - return pointInPolygon([ - [[-10, 80], [-10, 75], [10, 75], [10, 85], [-120, 80], [120, 80], [-10, 80]] - ]); - }, - "inside": { - "clockwise region": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 76])); - }, - "counter-clockwise region": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 89])); - } - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([0, 0])); - } - } - }, - "touching a pole": { - "hemisphere touching the South pole": { - topic: function(pointInPolygon) { - return pointInPolygon(_.geo.circle().angle(90)().coordinates); - }, - "origin is inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 0])); - } - }, - "triangle touching the South pole": { - topic: function(pointInPolygon) { - return pointInPolygon([[[180, -90], [-45, 0], [45, 0], [180, -90]]]); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([-44, 0])); - assert.ok(pointInPolygon([0, 0])); - assert.ok(pointInPolygon([0, -30])); - assert.ok(pointInPolygon([30, -80])); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([-46, 0])); - assert.ok(!pointInPolygon([0, 1])); - assert.ok(!pointInPolygon([-90, -80])); - } - }, - "triangle touching the South pole (2)": { - topic: function(pointInPolygon) { - return pointInPolygon([[[-45, 0], [45, 0], [180, -90], [-45, 0]]]); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([-44, 0])); - assert.ok(pointInPolygon([0, 0])); - assert.ok(pointInPolygon([0, -30])); - assert.ok(pointInPolygon([30, -80])); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([-46, 0])); - assert.ok(!pointInPolygon([0, 1])); - assert.ok(!pointInPolygon([-90, -80])); - } - }, - "triangle touching the South pole (3)": { - topic: function(pointInPolygon) { - return pointInPolygon([[[180, -90], [-135, 0], [135, 0], [180, -90]]]); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([0, 0])); - assert.ok(pointInPolygon([180, 1])); - assert.ok(pointInPolygon([-90, -80])); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([180, 0])); - assert.ok(!pointInPolygon([150, 0])); - assert.ok(!pointInPolygon([180, -30])); - assert.ok(!pointInPolygon([150, -80])); - } - }, - "triangle touching the North pole": { - topic: function(pointInPolygon) { - return pointInPolygon([[[180, 90], [45, 0], [-45, 0], [180, 90]]]); - }, - "inside": function(pointInPolygon) { - assert.ok(pointInPolygon([-44, 10])); - assert.ok(pointInPolygon([0, 10])); - assert.ok(pointInPolygon([30, 80])); - }, - "outside": function(pointInPolygon) { - assert.ok(!pointInPolygon([-90, 0])); - assert.ok(!pointInPolygon([0, -1])); - assert.ok(!pointInPolygon([0, -80])); - assert.ok(!pointInPolygon([-90, 1])); - assert.ok(!pointInPolygon([-90, 80])); - } - } - } - } -}); - -suite.export(module); diff --git a/test/geo/projection-test-suite.js b/test/geo/projection-test-suite.js deleted file mode 100644 index d780fd32c85bcd..00000000000000 --- a/test/geo/projection-test-suite.js +++ /dev/null @@ -1,29 +0,0 @@ -var assert = require("../assert"), - _ = require("../../"), - format = _.format("13.8f"); - -module.exports = function(suite, mapping) { - - for (var place in mapping) { - suite[place] = test(mapping[place][0], mapping[place][1]); - } - - function test(location, point) { - return function(projection) { - var actualLocation = projection.invert(point), - actualPoint = projection(location); - try { - assert.inDelta([actualPoint, actualLocation], [point, location], 1e-5); - } catch (e) { - e.message = "project [[" - + location.map(format).join(", ") + "], [" + actualPoint.map(format).join(", ") - + "]]\n invert [[" - + actualLocation.map(format).join(", ") + "], [" + point.map(format).join(", ") - + "]]"; - throw e; - } - }; - } - - return suite; -}; diff --git a/test/geo/projection-test.js b/test/geo/projection-test.js deleted file mode 100644 index b68d373855edc9..00000000000000 --- a/test/geo/projection-test.js +++ /dev/null @@ -1,58 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.projection"); - -suite.addBatch({ - "projection": { - topic: load("geo/projection").expression("d3.geo.projection"), - "a custom invertible projection": { - topic: function(projection) { - function forward(λ, φ) { return [λ, φ]; } - forward.invert = function(x, y) {}; - return projection(forward); - }, - - "invert": { - "can return undefined": function(projection) { - assert.isUndefined(projection.invert([0, 0])); - } - }, - - "scale": { - "defaults to 150": function(projection) { - assert.equal(projection.scale(), 150); - }, - "is coerced to a number": function(projection) { - assert.strictEqual(projection.scale("400"), projection); - assert.strictEqual(projection.scale(), 400); - } - }, - - "translate": { - "defaults to [480, 250]": function(projection) { - assert.deepEqual(projection.translate(), [480, 250]); - }, - "is coerced to two numbers": function(projection) { - assert.strictEqual(projection.translate(["23", "141"]), projection); - assert.strictEqual(projection.translate()[0], 23); - assert.strictEqual(projection.translate()[1], 141); - } - }, - - "rotate": { - "defaults to [0, 0, 0]": function(projection) { - assert.deepEqual(projection.rotate(), [0, 0, 0]); - }, - "is coerced to three numbers": function(projection) { - assert.strictEqual(projection.rotate(["23", "41"]), projection); - assert.strictEqual(projection.rotate()[0], 23); - assert.strictEqual(projection.rotate()[1], 41); - } - } - } - } -}); - -suite.export(module); diff --git a/test/geo/rotation-test.js b/test/geo/rotation-test.js deleted file mode 100644 index d664e43e8c0741..00000000000000 --- a/test/geo/rotation-test.js +++ /dev/null @@ -1,35 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.rotation"); - -suite.addBatch({ - "rotation": { - topic: load("geo/rotation").expression("d3.geo.rotation"), - "a rotation of [+90°, 0°]": { - topic: function(rotation) { - return rotation([90, 0]); - }, - "only rotates longitude": function(rotation) { - assert.inDelta(rotation([0, 0]), [90, 0], 1e-6); - }, - "wraps around when crossing the antimeridian": function(rotation) { - assert.inDelta(rotation([150, 0]), [-120, 0], 1e-6); - } - }, - "a rotation of [-45°, -45°]": { - topic: function(rotation) { - return rotation([-45, 45]); - }, - "rotates longitude and latitude": function(rotation) { - assert.inDelta(rotation([0, 0]), [-54.73561, 30], 1e-6); - }, - "inverse rotation of longitude and latitude": function(rotation) { - assert.inDelta(rotation.invert([-54.73561, 30]), [0, 0], 1e-6); - } - } - } -}); - -suite.export(module); diff --git a/test/geo/stereographic-test.js b/test/geo/stereographic-test.js deleted file mode 100644 index 098719834e5f6c..00000000000000 --- a/test/geo/stereographic-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.stereographic"); - -suite.addBatch({ - "stereographic": { - topic: load("geo/stereographic").expression("d3.geo.stereographic"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 473.84094732, 117.14003304]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 459.00877672, 123.45642208]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 482.65216217, 160.62316700]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 449.13660231, 342.87385937]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 493.06074697, 121.99919699]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 387.44967610]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 112.55032390]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.04106035, -0.88573312]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.13994149, -0.84362385]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.01768108, -0.59584555]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.20575598, 0.61915906]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.08707165, -0.85333869]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 0.91633117]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -0.91633117]] - }) - } -}); - -suite.export(module); diff --git a/test/geo/stream-test.js b/test/geo/stream-test.js deleted file mode 100644 index e25318b0e5a972..00000000000000 --- a/test/geo/stream-test.js +++ /dev/null @@ -1,214 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geo.stream"); - -suite.addBatch({ - "stream": { - topic: load("geo/stream").expression("d3.geo.stream"), - "does not allow null input": function(stream) { - try { - stream(null); - assert.fail("expected error"); - } catch (expected) {} - }, - "ignores unknown types": function(stream) { - stream({type: "Unknown"}, {}); - stream({type: "Feature", geometry: {type: "Unknown"}}, {}); - stream({type: "FeatureCollection", features: [{type: "Feature", geometry: {type: "Unknown"}}]}, {}); - stream({type: "GeometryCollection", geometries: [{type: "Unknown"}]}, {}); - }, - "ignores null geometries": function(stream) { - stream(null, {}); - stream({type: "Feature", geometry: null}, {}); - stream({type: "FeatureCollection", features: [{type: "Feature", geometry: null}]}, {}); - stream({type: "GeometryCollection", geometries: [null]}, {}); - }, - "returns void": function(stream) { - assert.isUndefined(stream({type: "Point", coordinates: [1, 2]}, {point: function() { return true; }})); - }, - "allows empty multi-geometries": function(stream) { - stream({type: "MultiPoint", coordinates: []}, {}); - stream({type: "MultiLineString", coordinates: []}, {}); - stream({type: "MultiPolygon", coordinates: []}, {}); - }, - "Sphere ↦ sphere": function(stream) { - var calls = 0; - stream({type: "Sphere"}, { - sphere: function() { - assert.equal(arguments.length, 0); - assert.equal(++calls, 1); - } - }); - assert.equal(calls, 1); - }, - "Point ↦ point": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "Point", coordinates: [1, 2, 3]}, { - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.equal(++calls, 1); - } - }); - assert.equal(calls, 1); - }, - "MultiPoint ↦ point*": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "MultiPoint", coordinates: [[1, 2, 3], [4, 5, 6]]}, { - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.isTrue(1 <= ++calls && calls <= 2); - } - }); - assert.equal(calls, 2); - }, - "LineString ↦ lineStart, point{2,}, lineEnd": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "LineString", coordinates: [[1, 2, 3], [4, 5, 6]]}, { - lineStart: function() { - assert.equal(arguments.length, 0); - assert.equal(++calls, 1); - }, - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.isTrue(2 <= ++calls && calls <= 3); - }, - lineEnd: function() { - assert.equal(arguments.length, 0); - assert.equal(++calls, 4); - } - }); - assert.equal(calls, 4); - }, - "MultiLineString ↦ (lineStart, point{2,}, lineEnd)*": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "MultiLineString", coordinates: [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]}, { - lineStart: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 1 || calls === 5); - }, - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.isTrue(2 <= ++calls && calls <= 3 || 6 <= calls && calls <= 7); - }, - lineEnd: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 4 || calls === 8); - } - }); - assert.equal(calls, 8); - }, - "Polygon ↦ polygonStart, lineStart, point{2,}, lineEnd, polygonEnd": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "Polygon", coordinates: [[[1, 2, 3], [4, 5, 6], [1, 2, 3]], [[7, 8, 9], [10, 11, 12], [7, 8, 9]]]}, { - polygonStart: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 1); - }, - lineStart: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 2 || calls === 6); - }, - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.isTrue(3 <= ++calls && calls <= 4 || 7 <= calls && calls <= 8); - }, - lineEnd: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 5 || calls === 9); - }, - polygonEnd: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 10); - } - }); - assert.equal(calls, 10); - }, - "MultiPolygon ↦ (polygonStart, lineStart, point{2,}, lineEnd, polygonEnd)*": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "MultiPolygon", coordinates: [[[[1, 2, 3], [4, 5, 6], [1, 2, 3]]], [[[7, 8, 9], [10, 11, 12], [7, 8, 9]]]]}, { - polygonStart: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 1 || calls === 7); - }, - lineStart: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 2 || calls === 8); - }, - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.isTrue(3 <= ++calls && calls <= 4 || 9 <= calls && calls <= 10); - }, - lineEnd: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 5 || calls === 11); - }, - polygonEnd: function() { - assert.equal(arguments.length, 0); - assert.isTrue(++calls === 6 || calls === 12); - } - }); - assert.equal(calls, 12); - }, - "Feature ↦ .*": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "Feature", geometry: {type: "Point", coordinates: [1, 2, 3]}}, { - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.equal(++calls, 1); - } - }); - assert.equal(calls, 1); - }, - "FeatureCollection ↦ .*": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "FeatureCollection", features: [{type: "Feature", geometry: {type: "Point", coordinates: [1, 2, 3]}}]}, { - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.equal(++calls, 1); - } - }); - assert.equal(calls, 1); - }, - "GeometryCollection ↦ .*": function(stream) { - var calls = 0, coordinates = 0; - stream({type: "GeometryCollection", geometries: [{type: "Point", coordinates: [1, 2, 3]}]}, { - point: function(x, y, z) { - assert.equal(arguments.length, 3); - assert.equal(x, ++coordinates); - assert.equal(y, ++coordinates); - assert.equal(z, ++coordinates); - assert.equal(++calls, 1); - } - }); - assert.equal(calls, 1); - } - } -}); - -suite.export(module); diff --git a/test/geo/transverse-mercator-test.js b/test/geo/transverse-mercator-test.js deleted file mode 100644 index 119087e5e02646..00000000000000 --- a/test/geo/transverse-mercator-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - projectionTestSuite = require("./projection-test-suite"); - -var suite = vows.describe("d3.geo.transverseMercator"); - -suite.addBatch({ - "transverseMercator": { - topic: load("geo/transverse-mercator").expression("d3.geo.transverseMercator"), - "default": projectionTestSuite({ - topic: function(projection) { return projection(); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 480.00000000, 250.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349103], [ 473.09890692, 32.39629813]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ 455.53607488, 38.07095444]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 483.91452378, 88.76181349]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ 435.43771875, 420.48139861]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 495.09974957, 37.42095689]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 480.00000000, 472.52947963]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 480.00000000, 27.47052037]] - }), - "translated to 0,0 and at scale 1": projectionTestSuite({ - topic: function(projection) { return projection().translate([0, 0]).scale(1); } - }, { - "Null Island": [[ 0.00000000, 0.00000000], [ 0.00000000, 0.00000000]], - "Honolulu, HI": [[ -21.01262744, 82.63349120], [ -0.04600729, -1.45069135]], - "San Francisco, CA": [[ -46.16620803, 77.04946507], [ -0.16309283, -1.41286030]], - "Svalbard": [[ 3.13977663, 61.55241523], [ 0.02609683, -1.07492124]], - "Tierra del Fuego": [[ -35.62300462, -60.29317484], [ -0.29708188, 1.13654266]], - "Tokyo": [[ 33.38709832, 79.49539834], [ 0.10066500, -1.41719362]], - "the South Pole": [[ 0.00000000, -85.00000000], [ 0.00000000, 1.48352986]], - "the North Pole": [[ 0.00000000, 85.00000000], [ 0.00000000, -1.48352986]] - }) - } -}); - -suite.export(module); diff --git a/test/geom/hull-test.js b/test/geom/hull-test.js deleted file mode 100644 index 39db767776a4d5..00000000000000 --- a/test/geom/hull-test.js +++ /dev/null @@ -1,68 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geom.hull"); - -suite.addBatch({ - "hull": { - topic: load("geom/hull").expression("d3.geom.hull"), - "the default hull layout": { - topic: function(hull) { - return hull(); - }, - "has the default x-accessor, d[0]": function(h) { - assert.strictEqual(h.x()([42, 43]), 42); - }, - "has the default y-accessor, d[1]": function(h) { - assert.strictEqual(h.y()([42, 43]), 43); - }, - "of no points is empty": function(h) { - assert.deepEqual(h([]), []); - }, - "of one point is empty": function(h) { - assert.deepEqual(h([[200, 200]]), []); - }, - "of two points is empty": function(h) { - assert.deepEqual(h([[200, 200], [760, 300]]), []); - }, - "for three points": function(h) { - assert.deepEqual(h([[200, 200], [760, 300], [500, 500]]), [[500, 500], [760, 300], [200, 200]]); - }, - "for four points": function(h) { - assert.deepEqual(h([[200, 200], [760, 300], [500, 500], [400, 400]]), [[500, 500], [760, 300], [200, 200]]); - }, - "returns a counter-clockwise polygon": function(h) { - assert.greater(_.geom.polygon(h([[200, 200], [760, 300], [500, 500], [400, 400]])).area(), 0); - } - }, - "the hull layout with custom accessors": { - topic: function(hull) { - return hull().x(function(d) { return d.x; }).y(function(d) { return d.y; }); - }, - "of four points": function(h) { - assert.deepEqual(h([{x: 200, y: 200}, {x: 760, y: 300}, {x: 500, y: 500}, {x: 400, y: 400}]), [{x: 500, y: 500}, {x: 760, y: 300}, {x: 200, y: 200}]); - } - }, - "the default hull layout applied directly": { - "for no points is empty": function(h) { - return h([]); - }, - "for one point is empty": function(h) { - return h([[200, 200]]); - }, - "for two points is empty": function(h) { - return h([[200, 200], [760, 300]]); - }, - "for three points": function(h) { - assert.deepEqual(h([[200, 200], [760, 300], [500, 500]]), [[500, 500], [760, 300], [200, 200]]); - }, - "for four points": function(h) { - assert.deepEqual(h([[200, 200], [760, 300], [500, 500], [400, 400]]), [[500, 500], [760, 300], [200, 200]]); - } - } - } -}); - -suite.export(module); diff --git a/test/geom/polygon-test.js b/test/geom/polygon-test.js deleted file mode 100644 index 054292e06369cf..00000000000000 --- a/test/geom/polygon-test.js +++ /dev/null @@ -1,151 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geom.polygon"); - -suite.addBatch({ - "polygon": { - topic: load("geom/polygon").expression("d3.geom.polygon"), - "closed counterclockwise unit square": { - topic: function(polygon) { - return polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]); - }, - "preserves input coordinates": function(p) { - assertPolygonInDelta(p, [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]); - }, - "has area 1": function(p) { - assert.equal(p.area(), 1); - }, - "has centroid ⟨.5,.5⟩": function(p) { - assertPointInDelta(p.centroid(), [.5, .5]); - }, - "can clip an open counterclockwise triangle": function(p) { - assertPolygonInDelta(p.clip([[0.9, 0.5], [2, -1], [0.5, 0.1]]), [[0.9, 0.5], [1, 0.363636], [1, 0], [0.636363, 0], [0.5, 0.1]], 1e-4); - }, - "can clip a closed counterclockwise triangle": function(p) { - assertPolygonInDelta(p.clip([[0.9, 0.5], [2, -1], [0.5, 0.1], [0.9, 0.5]]), [[0.9, 0.5], [1, 0.363636], [1, 0], [0.636363, 0], [0.5, 0.1], [0.9, 0.5]], 1e-4); - } - }, - "closed clockwise unit square": { - topic: function(polygon) { - return polygon([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]); - }, - "preserves input coordinates": function(p) { - assertPolygonInDelta(p, [[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]); - }, - "has area 1": function(p) { - assert.equal(p.area(), -1); - }, - "has centroid ⟨.5,.5⟩": function(p) { - assertPointInDelta(p.centroid(), [.5, .5]); - }, - "is not currently supported for clipping": function(p) { - // because clipping requires a counterclockwise source polygon - } - }, - "closed clockwise triangle": { - topic: function(polygon) { - return polygon([[1, 1], [3, 2], [2, 3], [1, 1]]); - }, - "preserves input coordinates": function(p) { - assertPolygonInDelta(p, [[1, 1], [3, 2], [2, 3], [1, 1]]); - }, - "has area 1.5": function(p) { - assert.equal(p.area(), -1.5); - }, - "has centroid ⟨2,2⟩": function(p) { - assertPointInDelta(p.centroid(), [2, 2]); - }, - "is not currently supported for clipping": function(p) { - // because clipping requires a counterclockwise source polygon - } - }, - "open counterclockwise unit square": { - topic: function(polygon) { - return polygon([[0, 0], [0, 1], [1, 1], [1, 0]]); - }, - "remains an open polygon": function(p) { - assertPolygonInDelta(p, [[0, 0], [0, 1], [1, 1], [1, 0]]); - }, - "has area 1": function(p) { - assert.equal(p.area(), 1); - }, - "has centroid ⟨.5,.5⟩": function(p) { - assertPointInDelta(p.centroid(), [.5, .5]); - }, - "can clip an open counterclockwise triangle": function(p) { - assertPolygonInDelta(p.clip([[0.9, 0.5], [2, -1], [0.5, 0.1]]), [[0.9, 0.5], [1, 0.363636], [1, 0], [0.636363, 0], [0.5, 0.1]], 1e-4); - }, - "can clip an closed counterclockwise triangle": function(p) { - assertPolygonInDelta(p.clip([[0.9, 0.5], [2, -1], [0.5, 0.1], [0.9, 0.5]]), [[0.9, 0.5], [1, 0.363636], [1, 0], [0.636363, 0], [0.5, 0.1], [0.9, 0.5]], 1e-4); - } - }, - "open clockwise unit square": { - topic: function(polygon) { - return polygon([[0, 0], [1, 0], [1, 1], [0, 1]]); - }, - "remains an open polygon": function(p) { - assertPolygonInDelta(p, [[0, 0], [1, 0], [1, 1], [0, 1]]); - }, - "has area 1": function(p) { - assert.equal(p.area(), -1); - }, - "has centroid ⟨.5,.5⟩": function(p) { - assertPointInDelta(p.centroid(), [.5, .5]); - }, - "is not currently supported for clipping": function(p) { - // because clipping requires a counterclockwise source polygon - } - }, - "open clockwise triangle": { - topic: function(polygon) { - return polygon([[1, 1], [3, 2], [2, 3]]); - }, - "remains an open polygon": function(p) { - assertPolygonInDelta(p, [[1, 1], [3, 2], [2, 3]]); - }, - "has area 1.5": function(p) { - assert.equal(p.area(), -1.5); - }, - "has centroid ⟨2,2⟩": function(p) { - assertPointInDelta(p.centroid(), [2, 2]); - } - }, - "large square": { - topic: function(polygon) { - var r = 1e8, - d = _.range(0, r, r / 1e4); - return polygon( - d.map(function(y) { return [0, y]; }).concat( - d.map(function(x) { return [x, r]; })).concat( - d.map(function(y) { return [r, y]; }).reverse()).concat( - d.map(function(x) { return [x, 0]; }).reverse())); - }, - "has area 1e16 - 5e7": function(p) { - assert.equal(p.area(), 1e16 - 5e7); - } - } - } -}); - -function assertPointInDelta(expected, actual, δ, message) { - if (!δ) δ = 0; - if (!pointInDelta(expected, actual, δ)) { - assert.fail(JSON.stringify(actual), JSON.stringify(expected), message || "expected {expected}, got {actual}", "===", assertPointInDelta); - } -} - -function assertPolygonInDelta(expected, actual, δ, message) { - if (!δ) δ = 0; - if (expected.length !== actual.length || expected.some(function(e, i) { return !pointInDelta(e, actual[i], δ); })) { - assert.fail(JSON.stringify(actual), JSON.stringify(expected), message || "expected {expected}, got {actual}", "===", assertPolygonInDelta); - } -} - -function pointInDelta(a, b, δ) { - return !(Math.abs(a[0] - b[0]) > δ || Math.abs(a[1] - b[1]) > δ); -} - -suite.export(module); diff --git a/test/geom/quadtree-test.js b/test/geom/quadtree-test.js deleted file mode 100644 index aae2f40992dd52..00000000000000 --- a/test/geom/quadtree-test.js +++ /dev/null @@ -1,139 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geom.quadtree"); - -suite.addBatch({ - "quadtree": { - topic: load("geom/quadtree").expression("d3.geom.quadtree"), - "the default quadtree layout": { - topic: function(quadtree) { - return quadtree(); - }, - "has no defined size": function(q) { - assert.isNull(q.size()); - }, - "has no defined extent": function(q) { - assert.isNull(q.extent()); - }, - "has the default x-accessor, d[0]": function(q) { - assert.strictEqual(q.x()([42, 43]), 42); - }, - "has the default y-accessor, d[1]": function(q) { - assert.strictEqual(q.y()([42, 43]), 43); - }, - "can create a single-node quadtree with no bounds": function(q) { - var point = [0, 0], - q = q([point]), - n = 0; - q.visit(function(node, x1, y1, x2, y2) { - assert.deepEqual(node.point, point); - assert.isUndefined(node[0]); - assert.isUndefined(node[1]); - assert.isUndefined(node[2]); - assert.isUndefined(node[3]); - assert.isTrue(node.leaf); - ++n; - }); - assert.strictEqual(n, 1, "number of visits"); - } - }, - "the quadtree applied directly": { - "can create a single-node quadtree with no bounds": function(quadtree) { - var point = {x: 0, y: 0}, - q = quadtree([point]), - n = 0; - q.visit(function(node, x1, y1, x2, y2) { - assert.deepEqual(node.point, point); - assert.isUndefined(node[0]); - assert.isUndefined(node[1]); - assert.isUndefined(node[2]); - assert.isUndefined(node[3]); - assert.isTrue(node.leaf); - ++n; - }); - assert.strictEqual(n, 1, "number of visits"); - }, - "can create an empty quadtree": function(quadtree) { - var q = quadtree([], 8, 10, 56, 47), - n = 0; - q.visit(function(node, x1, y1, x2, y2) { - assert.isNull(node.point); - assert.isUndefined(node[0]); - assert.isUndefined(node[1]); - assert.isUndefined(node[2]); - assert.isUndefined(node[3]); - assert.isTrue(node.leaf); - ++n; - }); - assert.strictEqual(n, 1, "number of visits"); - }, - "squarifies the input dimensions": function(quadtree) { - var ox1 = 8, - oy1 = 10, - ox2 = 56, - oy2 = 47, - q = quadtree([], ox1, oy1, ox2, oy2), - n = 0; - q.visit(function(node, x1, y1, x2, y2) { - assert.strictEqual(x1, ox1); - assert.strictEqual(y1, oy1); - assert.strictEqual(x2, Math.max(ox2 - ox1, oy2 - oy1) + x1); - assert.strictEqual(y2, Math.max(ox2 - ox1, oy2 - oy1) + y1); - ++n; - }); - assert.strictEqual(n, 1, "number of visits"); - }, - "with three arguments, x1 and y1 are 0,0": function(quadtree) { - var dx = 56, - dy = 47, - q = quadtree([], dx, dy), - n = 0; - q.visit(function(node, x1, y1, x2, y2) { - assert.strictEqual(x1, 0); - assert.strictEqual(y1, 0); - assert.strictEqual(x2, Math.max(dx, dy)); - assert.strictEqual(y2, Math.max(dx, dy)); - ++n; - }); - assert.strictEqual(n, 1, "number of visits"); - }, - "visit": { - "uses pre-order traversal": function(quadtree) { - var a = {x: 100, y: 100}, - b = {x: 200, y: 200}, - c = {x: 300, y: 300}, - q = quadtree([a, b, c], 960, 500), - expected = [ - {point: null, x1: 0, y1: 0, x2: 960, y2: 960}, - {point: null, x1: 0, y1: 0, x2: 480, y2: 480}, - {point: null, x1: 0, y1: 0, x2: 240, y2: 240}, - {point: a, x1: 0, y1: 0, x2: 120, y2: 120}, - {point: b, x1: 120, y1: 120, x2: 240, y2: 240}, - {point: c, x1: 240, y1: 240, x2: 480, y2: 480} - ]; - q.visit(function(node, x1, y1, x2, y2) { - assert.deepEqual({point: node.point, x1: x1, y1: y1, x2: x2, y2: y2}, expected.shift()); - assert.equal(!!node.point, node.leaf); - }); - assert.isEmpty(expected); - }, - "does not recurse if the callback returns truthy": function(quadtree) { - var a = {x: 100, y: 100}, - b = {x: 700, y: 700}, - c = {x: 800, y: 800}, - q = quadtree([a, b, c], 960, 500), - n = 0; - q.visit(function(node, x1, y1, x2, y2) { - ++n; - return x1 > 0; - }); - assert.equal(n, 3); - } - } - } - } -}); - -suite.export(module); diff --git a/test/geom/voronoi-test.js b/test/geom/voronoi-test.js deleted file mode 100644 index d6963156d7b1c9..00000000000000 --- a/test/geom/voronoi-test.js +++ /dev/null @@ -1,230 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.geom.voronoi"); - -suite.addBatch({ - "voronoi": { - topic: load("geom/voronoi").expression("d3.geom.voronoi"), - - "the default voronoi layout": { - topic: function(voronoi) { - return voronoi(); - }, - "has no defined clip extent": function(v) { - assert.isNull(v.clipExtent()); - }, - "has no defined size": function(v) { - assert.isNull(v.size()); - }, - "returns the configured clip extent": function(v) { - try { - assert.deepEqual(v.clipExtent([[1, 2], [3, 4]]).clipExtent(), [[1, 2], [3, 4]]); - } finally { - v.clipExtent(null); - } - }, - "returns the configured size": function(v) { - try { - assert.deepEqual(v.size([1, 2]).size(), [1, 2]); - } finally { - v.size(null); - } - }, - "size implies a clip extent from [0, 0]": function(v) { - try { - assert.deepEqual(v.size([1, 2]).clipExtent(), [[0, 0], [1, 2]]); - } finally { - v.size(null); - } - }, - "clip extent implies a size, assuming [0, 0]": function(v) { - try { - assert.deepEqual(v.clipExtent([[1, 2], [3, 4]]).size(), [3, 4]); - } finally { - v.clipExtent(null); - } - }, - "has the default x-accessor, d[0]": function(v) { - assert.strictEqual(v.x()([42, 43]), 42); - }, - "has the default y-accessor, d[1]": function(v) { - assert.strictEqual(v.y()([42, 43]), 43); - }, - "of two points": { - topic: function(v) { - return v([[200, 200], [760, 300]]); - }, - "returns two cells with the expected geometry": function(cells) { - assert.inDelta(cells, [ - [[-178046.7857142857, 1e6], [179096.07142857145, -1e6], [-1e6, 1e6], [1e6, 1e6]], - [[-178046.7857142857, 1e6], [179096.07142857145, -1e6], [-1e6, -1e6], [1e6, -1e6]] - ], 1e-6); - }, - "the returned cells are open polygons": function(cells) { - cells.forEach(function(cell) { - assert.greater(cell.length, 2); - cell.forEach(function(point) { - assert.equal(point.length, 2); - assert.isNumber(point[0]); - assert.isNumber(point[1]); - }); - assert.notDeepEqual(cell[0], cell[cell.length - 1]); - }); - }, - "the returned cells are not clipped to the layout size": function(cells) { - var x0 = Infinity, x1 = -Infinity, y0 = Infinity, y1 = -Infinity; - cells.forEach(function(cell) { - cell.forEach(function(point) { - if (point[0] < x0) x0 = point[0]; - if (point[0] > x1) x1 = point[0]; - if (point[1] < y0) y0 = point[1]; - if (point[1] > y1) y1 = point[1]; - }); - }); - assert.strictEqual(x0, -1e6); - assert.strictEqual(x1, 1e6); - assert.strictEqual(y0, -1e6); - assert.strictEqual(y1, 1e6); - }, - "the returned cells' point property points back to the input point": function(cells) { - assert.deepEqual(cells.map(function(cell) { return cell.point; }), [[200, 200], [760, 300]]); - } - }, - "links": { - "for two points": function(v) { - assert.deepEqual(v.links([[200, 200], [760, 300]]), [ - {source: [200, 200], target: [760, 300]} - ]); - }, - "for three points": function(v) { - assert.deepEqual(v.links([[200, 200], [500, 250], [760, 300]]), [ - {source: [200, 200], target: [760, 300]}, - {source: [500, 250], target: [760, 300]}, - {source: [200, 200], target: [500, 250]} - ]); - } - }, - "triangles": { - "for three points": function(v) { - assert.deepEqual(asArray(v.triangles([[200, 200], [500, 250], [760, 300]])), [ - [[200, 200], [760, 300], [500, 250]] - ]); - } - } - }, - - "a voronoi layout with custom x- and y-accessors": { - topic: function(voronoi) { - return voronoi() - .x(function(d) { return d.x; }) - .y(43); - }, - "observes the specified x-accessor, a function": function(v) { - assert.strictEqual(v.x()({x: 42, y: 43}), 42); - }, - "observes the specified y-accessor, a constant": function(v) { - assert.strictEqual(v.y(), 43); - }, - "of two points": { - topic: function(v) { - return v([{x: 200}, {x: 760}]); - }, - "returns two cells with the expected geometry": function(cells) { - assert.inDelta(cells, [ - [[480, 1e6], [480, -1e6], [-1e6, -1e6], [-1e6, 1e6]], - [[480, -1e6], [480, 1e6], [1e6, -1e6], [1e6, 1e6]] - ], 1e-6); - } - }, - "links": { - topic: function(v) { - return v.y(function(d) { return d.y; }); - }, - "for two points": function(v) { - assert.deepEqual(v.links([{x: 200, y: 200}, {x: 760, y: 300}]), [ - {source: {x: 200, y: 200}, target: {x: 760, y: 300}} - ]); - }, - "for three points": function(v) { - assert.deepEqual(v.links([{x: 200, y: 200}, {x: 500, y: 250}, {x: 760, y: 300}]), [ - {source: {x: 200, y: 200}, target: {x: 760, y: 300}}, - {source: {x: 500, y: 250}, target: {x: 760, y: 300}}, - {source: {x: 200, y: 200}, target: {x: 500, y: 250}} - ]); - } - } - }, - - "a voronoi layout with clip extent [[0, 0], [960, 500]]": { - topic: function(voronoi) { - return voronoi() - .x(function(d) { return d.x; }) - .y(function(d) { return d.y; }) - .clipExtent([[0, 0], [960, 500]]); - }, - "of two points": { - topic: function(v) { - return v([{x: 200, y: 200}, {x: 760, y: 300}]); - }, - "returns two cells with the expected geometry": function(cells) { - assert.inDelta(cells, [ - [[435.35714285715324, 500], [524.6428571428696, 0], [0, 0], [0, 500]], - [[960, 0], [960, 500], [435.35714285715324, 500], [524.6428571428696, 0]] - ], 1e-6); - }, - "the returned cells are clipped to the layout size": function(cells) { - assert.isTrue(cells.every(function(cell) { - return cell.every(function(point) { - return point[0] >= 0 && point[0] <= 960 - && point[1] >= 0 && point[1] <= 500; - }); - })); - } - } - }, - - "the default voronoi layout applied directly": { - "with zero points": { - "returns the empty array": function(voronoi) { - assert.deepEqual(voronoi([]), []); - } - }, - "with one point": { - "returns the semi-infinite bounding box": function(voronoi) { - assert.deepEqual(asArray(voronoi([[50, 50]], 100, 100)), [[[-1000000,-1000000],[-1000000,1000000],[1000000,1000000],[1000000,-1000000]]]); - } - }, - "with two points": { - "separated by a line at 90° (vertical)": function(voronoi) { - assert.deepEqual(asArray(voronoi([[50, 25], [50, 75]], 100, 100)), [[[-1000000,50],[1000000,50],[-1000000,-1000000],[1000000,-1000000]],[[-1000000,50],[1000000,50],[-1000000,1000000],[1000000,1000000]]]); - assert.deepEqual(asArray(voronoi([[50, 75], [50, 25]], 100, 100)), [[[-1000000,50],[1000000,50],[-1000000,1000000],[1000000,1000000]],[[-1000000,50],[1000000,50],[-1000000,-1000000],[1000000,-1000000]]]); - }, - "separated by a line at 0° (horizontal)": function(voronoi) { - assert.deepEqual(asArray(voronoi([[25, 50], [75, 50]], 100, 100)), [[[50,1000000],[50,-1000000],[-1000000,-1000000],[-1000000,1000000]],[[50,-1000000],[50,1000000],[1000000,-1000000],[1000000,1000000]]]); - assert.deepEqual(asArray(voronoi([[75, 50], [25, 50]], 100, 100)), [[[50,-1000000],[50,1000000],[1000000,-1000000],[1000000,1000000]],[[50,1000000],[50,-1000000],[-1000000,-1000000],[-1000000,1000000]]]); - }, - "separated by a line at 45° (diagonal)": function(voronoi) { - assert.deepEqual(asArray(voronoi([[25, 25], [75, 75]], 100, 100)), [[[-999900,1000000],[1000100,-1000000],[-1000000,-1000000]],[[-999900,1000000],[1000100,-1000000],[1000000,1000000]]]); - assert.deepEqual(asArray(voronoi([[75, 25], [25, 75]], 100, 100)), [[[-1000000,-1000000],[1000000,1000000],[1000000,-1000000]],[[-1000000,-1000000],[1000000,1000000],[-1000000,1000000]]]); - }, - "separated by an arbitrary diagonal": function(voronoi) { - assert.deepEqual(asArray(voronoi([[25, 25], [50, 75]], 100, 100)), [[[-1000000,500068.75],[1000000,-499931.25],[-1000000,-1000000],[1000000,-1000000]],[[-1000000,500068.75],[1000000,-499931.25],[-1000000,1000000],[1000000,1000000]]]); - assert.deepEqual(asArray(voronoi([[25, 25], [75, 50]], 100, 100)), [[[-499931.25,1000000],[500068.75,-1000000],[-1000000,1000000],[1000000,1000000]], [[-499931.25,1000000],[500068.75,-1000000],[-1000000,-1000000],[1000000,-1000000]]]); - } - }, - "with three points": { - "collinear": function(voronoi) { - assert.deepEqual(asArray(voronoi([[25, 25], [50, 50], [75, 75]], 100, 100)), [[[-999925,1000000],[1000075,-1000000],[-1000000,-1000000]],[[-999925,1000000],[-999875,1000000],[1000125,-1000000],[1000075,-1000000]],[[-999875,1000000],[1000125,-1000000],[1000000,1000000]]]); - } - } - } - } -}); - -suite.export(module); - -function asArray(array) { - return Array.isArray(array) ? array.map(asArray) : array; -} diff --git a/test/interpolate/array-test.js b/test/interpolate/array-test.js deleted file mode 100644 index 34ac6ef9d14a2a..00000000000000 --- a/test/interpolate/array-test.js +++ /dev/null @@ -1,24 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateArray"); - -suite.addBatch({ - "interpolateArray": { - topic: load("interpolate/array").expression("d3.interpolateArray"), - "interpolates defined elements": function(interpolate) { - assert.deepEqual(interpolate([2, 12], [4, 24])(.5), [3, 18]); - }, - "interpolates nested objects and arrays": function(interpolate) { - assert.deepEqual(interpolate([[2, 12]], [[4, 24]])(.5), [[3, 18]]); - assert.deepEqual(interpolate([{foo: [2, 12]}], [{foo: [4, 24]}])(.5), [{foo: [3, 18]}]); - }, - "merges non-shared elements": function(interpolate) { - assert.deepEqual(interpolate([2, 12], [4, 24, 12])(.5), [3, 18, 12]); - assert.deepEqual(interpolate([2, 12, 12], [4, 24])(.5), [3, 18, 12]); - } - } -}); - -suite.export(module); diff --git a/test/interpolate/ease-test.js b/test/interpolate/ease-test.js deleted file mode 100644 index 7e365486db6898..00000000000000 --- a/test/interpolate/ease-test.js +++ /dev/null @@ -1,135 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.ease"); - -suite.addBatch({ - "ease": { - topic: load("interpolate/ease").expression("d3.ease"), - "supports linear easing": function(ease) { - var e = ease("linear"); - assert.inDelta(e(.5), .5, 1e-6); - }, - "supports polynomial easing": function(ease) { - var e = ease("poly", 2); - assert.inDelta(e(.5), .25, 1e-6); - }, - "supports quadratic easing": function(ease) { - var e = ease("quad"); - assert.inDelta(e(.5), .25, 1e-6); - }, - "supports cubic easing": function(ease) { - var e = ease("cubic"); - assert.inDelta(e(.5), .125, 1e-6); - }, - "supports sinusoidal easing": function(ease) { - var e = ease("sin"); - assert.inDelta(e(.5), 1 - Math.cos(Math.PI / 4), 1e-6); - }, - "supports exponential easing": function(ease) { - var e = ease("exp"); - assert.inDelta(e(.5), 0.03125, 1e-6); - }, - "supports circular easing": function(ease) { - var e = ease("circle"); - assert.inDelta(e(.5), 0.133975, 1e-6); - }, - "supports elastic easing": function(ease) { - var e = ease("elastic"); - assert.inDelta(e(.5), 0.976061, 1e-6); - }, - "supports back easing": function(ease) { - var e = ease("back"); - assert.inDelta(e(.5), -0.0876975, 1e-6); - }, - "supports bounce easing": function(ease) { - var e = ease("bounce"); - assert.inDelta(e(.5), 0.765625, 1e-6); - }, - "invalid eases and modes default to linear-in": function(ease) { - var e = ease("__proto__-__proto__"); - assert.strictEqual(e(0), 0); - assert.strictEqual(e(.5), .5); - assert.strictEqual(e(1), 1); - var e = ease("hasOwnProperty-constructor"); - assert.strictEqual(e(0), 0); - assert.strictEqual(e(.5), .5); - assert.strictEqual(e(1), 1); - }, - "all easing functions return exactly 0 for t = 0": function(ease) { - assert.strictEqual(ease("linear")(0), 0); - assert.strictEqual(ease("poly", 2)(0), 0); - assert.strictEqual(ease("quad")(0), 0); - assert.strictEqual(ease("cubic")(0), 0); - assert.strictEqual(ease("sin")(0), 0); - assert.strictEqual(ease("exp")(0), 0); - assert.strictEqual(ease("circle")(0), 0); - assert.strictEqual(ease("elastic")(0), 0); - assert.strictEqual(ease("back")(0), 0); - assert.strictEqual(ease("bounce")(0), 0); - }, - "all easing functions return exactly 1 for t = 1": function(ease) { - assert.strictEqual(ease("linear")(1), 1); - assert.strictEqual(ease("poly", 2)(1), 1); - assert.strictEqual(ease("quad")(1), 1); - assert.strictEqual(ease("cubic")(1), 1); - assert.strictEqual(ease("sin")(1), 1); - assert.strictEqual(ease("exp")(1), 1); - assert.strictEqual(ease("circle")(1), 1); - assert.strictEqual(ease("elastic")(1), 1); - assert.strictEqual(ease("back")(1), 1); - assert.strictEqual(ease("bounce")(1), 1); - }, - "the -in suffix returns the identity": function(ease) { - assert.inDelta(ease("linear-in")(.25), ease("linear")(.25), 1e-6); - assert.inDelta(ease("quad-in")(.75), ease("quad")(.75), 1e-6); - }, - "the -out suffix returns the reverse": function(ease) { - assert.inDelta(ease("sin-out")(.25), 1 - ease("sin-in")(.75), 1e-6); - assert.inDelta(ease("bounce-out")(.25), 1 - ease("bounce-in")(.75), 1e-6); - assert.inDelta(ease("elastic-out")(.25), 1 - ease("elastic-in")(.75), 1e-6); - }, - "the -in-out suffix returns the reflection": function(ease) { - assert.inDelta(ease("sin-in-out")(.25), .5 * ease("sin-in")(.5), 1e-6); - assert.inDelta(ease("bounce-in-out")(.25), .5 * ease("bounce-in")(.5), 1e-6); - assert.inDelta(ease("elastic-in-out")(.25), .5 * ease("elastic-in")(.5), 1e-6); - }, - "the -out-in suffix returns the reverse reflection": function(ease) { - assert.inDelta(ease("sin-out-in")(.25), .5 * ease("sin-out")(.5), 1e-6); - assert.inDelta(ease("bounce-out-in")(.25), .5 * ease("bounce-out")(.5), 1e-6); - assert.inDelta(ease("elastic-out-in")(.25), .5 * ease("elastic-out")(.5), 1e-6); - }, - "clamps input time": function(ease) { - var e = ease("linear"); - assert.inDelta(e(-1), 0, 1e-6); - assert.inDelta(e(2), 1, 1e-6); - }, - "poly": { - "supports an optional polynomial": function(ease) { - var e = ease("poly", 1); - assert.inDelta(e(.5), .5, 1e-6); - var e = ease("poly", .5); - assert.inDelta(e(.5), Math.SQRT1_2, 1e-6); - } - }, - "elastic": { - "supports an optional amplifier (>1)": function(ease) { - var e = ease("elastic", 1.5); - assert.inDelta(e(.5), 0.998519, 1e-6); - }, - "supports an optional amplifier (>1) and period (>0)": function(ease) { - var e = ease("elastic", 1.5, .5); - assert.inDelta(e(.5), 0.96875, 1e-6); - } - }, - "back": { - "supports an optional speed": function(ease) { - var e = ease("back", 2); - assert.inDelta(e(.5), -0.125, 1e-6); - } - } - } -}); - -suite.export(module); diff --git a/test/interpolate/hcl-test.js b/test/interpolate/hcl-test.js deleted file mode 100644 index f21ab3b125048b..00000000000000 --- a/test/interpolate/hcl-test.js +++ /dev/null @@ -1,47 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateHcl"); - -suite.addBatch({ - "interpolateHcl": { - topic: load("interpolate/hcl"), // beware instanceof d3_Color - "parses string input": function(d3) { - assert.strictEqual(d3.interpolateHcl("steelblue", "#f00")(.2), "#6978c9"); - assert.strictEqual(d3.interpolateHcl("steelblue", "#f00")(.6), "#e034a2"); - }, - "parses d3.hsl input": function(d3) { - assert.strictEqual(d3.interpolateHcl(d3.hsl("steelblue"), "#f00")(.2), "#6978c9"); - assert.strictEqual(d3.interpolateHcl("steelblue", d3.hsl(0, 1, .5))(.6), "#e034a2"); - }, - "parses d3.rgb input": function(d3) { - assert.strictEqual(d3.interpolateHcl(d3.rgb("steelblue"), "#f00")(.2), "#6978c9"); - assert.strictEqual(d3.interpolateHcl("steelblue", d3.rgb(255, 0, 0))(.6), "#e034a2"); - }, - "interpolates in HSL color space": function(d3) { - assert.strictEqual(d3.interpolateHcl("steelblue", "#f00")(.2), "#6978c9"); - }, - "uses source hue when destination hue is undefined": function(d3) { - assert.equal(d3.interpolateHcl("#f60", "#000")(.5), "#9b0000"); - assert.equal(d3.interpolateHcl("#6f0", "#000")(.5), "#008100"); - }, - "uses destination hue when source hue is undefined": function(d3) { - assert.equal(d3.interpolateHcl("#000", "#f60")(.5), "#9b0000"); - assert.equal(d3.interpolateHcl("#000", "#6f0")(.5), "#008100"); - }, - "uses source chroma when destination chroma is undefined": function(d3) { - assert.equal(d3.interpolateHcl("#ccc", "#000")(.5), "#616161"); - assert.equal(d3.interpolateHcl("#f00", "#000")(.5), "#a60000"); - }, - "uses destination chroma when source chroma is undefined": function(d3) { - assert.equal(d3.interpolateHcl("#000", "#ccc")(.5), "#616161"); - assert.equal(d3.interpolateHcl("#000", "#f00")(.5), "#a60000"); - }, - "outputs a hexadecimal string": function(d3) { - assert.strictEqual(d3.interpolateHcl("steelblue", "#f00")(.2), "#6978c9"); - } - } -}); - -suite.export(module); diff --git a/test/interpolate/hsl-test.js b/test/interpolate/hsl-test.js deleted file mode 100644 index 26689a30ba9646..00000000000000 --- a/test/interpolate/hsl-test.js +++ /dev/null @@ -1,47 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateHsl"); - -suite.addBatch({ - "interpolateHsl": { - topic: load("interpolate/hsl"), // beware instanceof d3_Color - "parses string input": function(d3) { - assert.strictEqual(d3.interpolateHsl("steelblue", "#f00")(.2), "#383dc3"); - assert.strictEqual(d3.interpolateHsl("steelblue", "#f00")(.6), "#dd1ce1"); - }, - "parses d3.hsl input": function(d3) { - assert.strictEqual(d3.interpolateHsl(d3.hsl("steelblue"), "#f00")(.2), "#383dc3"); - assert.strictEqual(d3.interpolateHsl("steelblue", d3.hsl(0, 1, .5))(.6), "#dd1ce1"); - }, - "parses d3.rgb input": function(d3) { - assert.strictEqual(d3.interpolateHsl(d3.rgb("steelblue"), "#f00")(.2), "#383dc3"); - assert.strictEqual(d3.interpolateHsl("steelblue", d3.rgb(255, 0, 0))(.6), "#dd1ce1"); - }, - "interpolates in HSL color space": function(d3) { - assert.strictEqual(d3.interpolateHsl("steelblue", "#f00")(.2), "#383dc3"); - }, - "uses source hue when destination hue is undefined": function(d3) { - assert.equal(d3.interpolateHsl("#f60", "#000")(.5), "#803300"); - assert.equal(d3.interpolateHsl("#6f0", "#fff")(.5), "#b3ff80"); - }, - "uses destination hue when source hue is undefined": function(d3) { - assert.equal(d3.interpolateHsl("#000", "#f60")(.5), "#803300"); - assert.equal(d3.interpolateHsl("#fff", "#6f0")(.5), "#b3ff80"); - }, - "uses source saturation when destination saturation is undefined": function(d3) { - assert.equal(d3.interpolateHsl("#ccc", "#000")(.5), "#666666"); - assert.equal(d3.interpolateHsl("#f00", "#000")(.5), "#800000"); - }, - "uses destination saturation when source saturation is undefined": function(d3) { - assert.equal(d3.interpolateHsl("#000", "#ccc")(.5), "#666666"); - assert.equal(d3.interpolateHsl("#000", "#f00")(.5), "#800000"); - }, - "outputs a hexadecimal string": function(d3) { - assert.strictEqual(d3.interpolateHsl("steelblue", "#f00")(.2), "#383dc3"); - } - } -}); - -suite.export(module); diff --git a/test/interpolate/interpolate-test.js b/test/interpolate/interpolate-test.js deleted file mode 100644 index 03b447059e9b44..00000000000000 --- a/test/interpolate/interpolate-test.js +++ /dev/null @@ -1,151 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolate"); - -suite.addBatch({ - "interpolate": { - topic: load("interpolate/interpolate"), - - "when b is a number": { - "interpolates numbers": function(d3) { - assert.strictEqual(d3.interpolate(2, 12)(.4), 6); - }, - "coerces a to a number": function(d3) { - assert.strictEqual(d3.interpolate("", 1)(.5), .5); - assert.strictEqual(d3.interpolate("2", 12)(.4), 6); - assert.strictEqual(d3.interpolate([2], 12)(.4), 6); - } - }, - - "when b is a color string": { - "interpolates RGB values and returns a hexadecimal string": function(d3) { - assert.strictEqual(d3.interpolate("#ff0000", "#008000")(.4), "#993300"); - }, - "interpolates named colors in RGB": function(d3) { - assert.strictEqual(d3.interpolate("red", "green")(.4), "#993300"); - }, - "interpolates decimal RGB colors in RGB": function(d3) { - assert.strictEqual(d3.interpolate("rgb(255,0,0)", "rgb(0,128,0)")(.4), "#993300"); - }, - "interpolates decimal HSL colors in RGB": function(d3) { - assert.strictEqual(d3.interpolate("hsl(0,100%,50%)", "hsl(120,100%,25%)")(.4), "#993300"); - }, - "coerces a to a color": function(d3) { - assert.strictEqual(d3.interpolate({toString: function() { return "red"; }}, "green")(.4), "#993300"); - } - }, - - "when b is a color object": { - "interpolates RGB values and returns a hexadecimal string": function(d3) { - assert.strictEqual(d3.interpolate(d3.rgb(255, 0, 0), d3.rgb(0, 128, 0))(.4), "#993300"); - }, - "interpolates d3.hsl in RGB": function(d3) { - assert.strictEqual(d3.interpolate(d3.hsl("red"), d3.hsl("green"))(.4), "#993300"); - }, - "interpolates d3.lab in RGB": function(d3) { - assert.strictEqual(d3.interpolate(d3.lab("red"), d3.lab("green"))(.4), "#993300"); - }, - "interpolates d3.hcl in RGB": function(d3) { - assert.strictEqual(d3.interpolate(d3.hcl("red"), d3.hcl("green"))(.4), "#993300"); - }, - "coerces a to a color": function(d3) { - assert.strictEqual(d3.interpolate({toString: function() { return "red"; }}, "green")(.4), "#993300"); - } - }, - - "when b is a string": { - "interpolates matching numbers in both strings": function(d3) { - assert.strictEqual(d3.interpolate(" 10/20 30", "50/10 100 ")(.4), "26/16 58 "); - }, - "if b is coercible to a number, still returns a string": function(d3) { - assert.strictEqual(d3.interpolate("1.", "2.")(.5), "1.5"); - assert.strictEqual(d3.interpolate("1e+3", "1e+4")(.5), "5500"); - }, - "preserves non-numbers in string b": function(d3) { - assert.strictEqual(d3.interpolate(" 10/20 30", "50/10 foo ")(.4), "26/16 foo "); - }, - "preserves non-matching numbers in string b": function(d3) { - assert.strictEqual(d3.interpolate(" 10/20 bar", "50/10 100 ")(.4), "26/16 100 "); - }, - "preserves equal-value numbers in both strings": function(d3) { - assert.strictEqual(d3.interpolate(" 10/20 100 20", "50/10 100, 20 ")(.4), "26/16 100, 20 "); - }, - "coerces a to a string": function(d3) { - assert.strictEqual(d3.interpolate({toString: function() { return "1."; }}, "2.")(.5), "1.5"); - } - }, - - "when b is an array": { - "interpolates each element in b": function(d3) { - assert.strictEqual(JSON.stringify(d3.interpolate([2, 4], [12, 24])(.4)), "[6,12]"); - }, - "interpolates arrays, even when both a and b are coercible to numbers": function(d3) { - assert.strictEqual(JSON.stringify(d3.interpolate([2], [12])(.4)), "[6]"); - assert.strictEqual(JSON.stringify(d3.interpolate([[2]], [[12]])(.4)), "[[6]]"); - }, - "reuses the returned array during interpolation": function(d3) { - var i = d3.interpolate([2], [12]); - assert.strictEqual(i(.2), i(.4)); - } - }, - - "when b is an object": { - "interpolates each property in b": function(d3) { - assert.deepEqual(d3.interpolate({foo: 2, bar: 4}, {foo: 12, bar: 24})(.4), {foo: 6, bar: 12}); - }, - "interpolates arrays, even when both a and b are coercible to numbers": function(d3) { - var two = new Number(2), twelve = new Number(12); - two.foo = "2px"; - twelve.foo = "12px"; - assert.deepEqual(d3.interpolate(two, twelve)(.4), {foo: "6px"}); - }, - "reuses the returned object during interpolation": function(d3) { - var i = d3.interpolate({foo: 2, bar: 4}, {foo: 12, bar: 24}); - assert.strictEqual(i(.2), i(.4)); - } - }, - - "may or may not interpolate between enumerable and non-enumerable properties": function(d3) { - var a = Object.create({}, {foo: {value: 1, enumerable: true}}), - b = Object.create({}, {foo: {value: 2, enumerable: false}}); - try { - assert.deepEqual(d3.interpolate(a, b)(1), {}); - } catch (e) { - assert.deepEqual(d3.interpolate(a, b)(1), {foo: 2}); - } - try { - assert.deepEqual(d3.interpolate(b, a)(1), {}); - } catch (e) { - assert.deepEqual(d3.interpolate(b, a)(1), {foo: 1}); - } - }, - "interpolates inherited properties of objects": function(d3) { - var a = Object.create({foo: 0}), - b = Object.create({foo: 2}); - assert.deepEqual(d3.interpolate(a, b)(.5), {foo: 1}); - }, - "doesn't interpret properties in the default object's prototype chain as RGB": function(d3) { - assert.equal(d3.interpolate("hasOwnProperty", "hasOwnProperty")(0), "hasOwnProperty"); - } - }, - - "interpolators": { - topic: load("interpolate/interpolate").document(), - "can register a custom interpolator": function(d3) { - d3.interpolators.push(function(a, b) { return a == "one" && b == "two" && d3.interpolateNumber(1, 2); }); - try { - assert.equal(d3.interpolate("one", "two")(-.5), .5); - assert.equal(d3.interpolate("one", "two")(0), 1); - assert.equal(d3.interpolate("one", "two")(.5), 1.5); - assert.equal(d3.interpolate("one", "two")(1), 2); - assert.equal(d3.interpolate("one", "two")(1.5), 2.5); - } finally { - d3.interpolators.pop(); - } - } - } -}); - -suite.export(module); diff --git a/test/interpolate/interpolate-transform-test.js b/test/interpolate/interpolate-transform-test.js deleted file mode 100644 index 5320740a0ab416..00000000000000 --- a/test/interpolate/interpolate-transform-test.js +++ /dev/null @@ -1,60 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateTransform"); - -suite.addBatch({ - "interpolateTransform": { - topic: load("interpolate/transform").document(), - "interpolation of a decomposed transform": { - topic: function(d3) { - // Use a custom d3.transform to parse a decomposed transform, since - // JSDOM doesn't support consolidating SVG transform strings. - d3.transform = function(s) { - var m = s.split(/,/g).map(Number); - return { - translate: [m[0], m[1]], - rotate: m[2], - skew: m[3], - scale: [m[4], m[5]] - }; - }; - return d3; - }, - "identity": function(d3) { - assert.strictEqual(d3.interpolateTransform([0, 0, 0, 0, 1, 1] + "", [0, 0, 0, 0, 1, 1] + "")(.4), ""); - }, - "translate": { - "x": function(d3) { - assert.strictEqual(d3.interpolateTransform([0, 0, 0, 0, 1, 1] + "", [10, 0, 0, 0, 1, 1] + "")(.4), "translate(4,0)"); - }, - "y": function(d3) { - assert.strictEqual(d3.interpolateTransform([0, 0, 0, 0, 1, 1] + "", [0, 10, 0, 0, 1, 1] + "")(.4), "translate(0,4)"); - }, - "x and y": function(d3) { - assert.strictEqual(d3.interpolateTransform([0, 0, 0, 0, 1, 1] + "", [1, 10, 0, 0, 1, 1] + "")(.4), "translate(0.4,4)"); - } - }, - "rotate": { - "simple": function(d3) { - assert.strictEqual(d3.interpolateTransform([0, 0, -10, 0, 1, 1] + "", [0, 0, 30, 0, 1, 1] + "")(.4), "rotate(6)"); - }, - "with constant translate": function(d3) { - assert.strictEqual(d3.interpolateTransform([5, 6, -10, 0, 1, 1] + "", [5, 6, 30, 0, 1, 1] + "")(.4), "translate(5,6)rotate(6)"); - } - }, - "skew": function(d3) { - assert.strictEqual(d3.interpolateTransform([0, 0, 0, 0, 1, 1] + "", [0, 0, 0, 40, 1, 1] + "")(.4), "skewX(16)"); - }, - "scale": function(d3) { - assert.strictEqual(d3.interpolateTransform([0, 0, 0, 0, 1, 1] + "", [0, 0, 0, 0, 10, 1] + "")(.5), "scale(5.5,1)"); - }, - "translate and rotate": function(d3) { - assert.strictEqual(d3.interpolateTransform([0, 0, 0, 0, 1, 1] + "", [100, 0, 90, 0, 1, 1] + "")(.5), "translate(50,0)rotate(45)"); - } - } - } -}); - -suite.export(module); diff --git a/test/interpolate/lab-test.js b/test/interpolate/lab-test.js deleted file mode 100644 index bb4622aa9031bf..00000000000000 --- a/test/interpolate/lab-test.js +++ /dev/null @@ -1,31 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateLab"); - -suite.addBatch({ - "interpolateLab": { - topic: load("interpolate/lab"), // beware instanceof d3_Color - "parses string input": function(d3) { - assert.strictEqual(d3.interpolateLab("steelblue", "#f00")(.2), "#8a7793"); - assert.strictEqual(d3.interpolateLab("steelblue", "#f00")(.6), "#cf5952"); - }, - "parses d3.hsl input": function(d3) { - assert.strictEqual(d3.interpolateLab(d3.hsl("steelblue"), "#f00")(.2), "#8a7793"); - assert.strictEqual(d3.interpolateLab("steelblue", d3.hsl(0, 1, .5))(.6), "#cf5952"); - }, - "parses d3.rgb input": function(d3) { - assert.strictEqual(d3.interpolateLab(d3.rgb("steelblue"), "#f00")(.2), "#8a7793"); - assert.strictEqual(d3.interpolateLab("steelblue", d3.rgb(255, 0, 0))(.6), "#cf5952"); - }, - "interpolates in HSL color space": function(d3) { - assert.strictEqual(d3.interpolateLab("steelblue", "#f00")(.2), "#8a7793"); - }, - "returns an instanceof d3.lab": function(d3) { - assert.strictEqual(d3.interpolateLab("steelblue", "#f00")(.2), "#8a7793"); - } - } -}); - -suite.export(module); diff --git a/test/interpolate/number-test.js b/test/interpolate/number-test.js deleted file mode 100644 index dd3f37d239f17c..00000000000000 --- a/test/interpolate/number-test.js +++ /dev/null @@ -1,20 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateNumber"); - -suite.addBatch({ - "interpolateNumber": { - topic: load("interpolate/number").expression("d3.interpolateNumber"), - "interpolates numbers": function(interpolate) { - assert.strictEqual(interpolate(2, 12)(.4), 6); - assert.strictEqual(interpolate(2, 12)(.6), 8); - }, - "coerces strings to numbers": function(interpolate) { - assert.strictEqual(interpolate("2", "12")(.4), 6); - } - } -}); - -suite.export(module); diff --git a/test/interpolate/object-test.js b/test/interpolate/object-test.js deleted file mode 100644 index f9539a66f30448..00000000000000 --- a/test/interpolate/object-test.js +++ /dev/null @@ -1,35 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateObject"); - -suite.addBatch({ - "interpolateObject": { - topic: load("interpolate/object").expression("d3.interpolateObject"), - "interpolates defined properties": function(interpolate) { - assert.deepEqual(interpolate({a: 2, b: 12}, {a: 4, b: 24})(.5), {a: 3, b: 18}); - }, - "interpolates inherited properties": function(interpolate) { - function a(a) { this.a = a; } - a.prototype.b = 12; - assert.deepEqual(interpolate(new a(2), new a(4))(.5), {a: 3, b: 12}); - }, - "interpolates color properties as rgb": function(interpolate) { - assert.deepEqual(interpolate({background: "red"}, {background: "green"})(.5), {background: "#804000"}); - assert.deepEqual(interpolate({fill: "red"}, {fill: "green"})(.5), {fill: "#804000"}); - assert.deepEqual(interpolate({stroke: "red"}, {stroke: "green"})(.5), {stroke: "#804000"}); - assert.deepEqual(interpolate({color: "red"}, {color: "green"})(.5), {color: "#804000"}); - }, - "interpolates nested objects and arrays": function(interpolate) { - assert.deepEqual(interpolate({foo: [2, 12]}, {foo: [4, 24]})(.5), {foo: [3, 18]}); - assert.deepEqual(interpolate({foo: {bar: [2, 12]}}, {foo: {bar: [4, 24]}})(.5), {foo: {bar: [3, 18]}}); - }, - "merges non-shared properties": function(interpolate) { - assert.deepEqual(interpolate({foo: 2}, {foo: 4, bar: 12})(.5), {foo: 3, bar: 12}); - assert.deepEqual(interpolate({foo: 2, bar: 12}, {foo: 4})(.5), {foo: 3, bar: 12}); - } - } -}); - -suite.export(module); diff --git a/test/interpolate/rgb-test.js b/test/interpolate/rgb-test.js deleted file mode 100644 index 89f9959575db90..00000000000000 --- a/test/interpolate/rgb-test.js +++ /dev/null @@ -1,31 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateRgb"); - -suite.addBatch({ - "interpolateRgb": { - topic: load("interpolate/rgb"), // beware instanceof d3_Color - "parses string input": function(d3) { - assert.strictEqual(d3.interpolateRgb("steelblue", "#f00")(.2), "#6b6890"); - assert.strictEqual(d3.interpolateRgb("steelblue", "#f00")(.6), "#b53448"); - }, - "parses d3.rgb input": function(d3) { - assert.strictEqual(d3.interpolateRgb(d3.rgb("steelblue"), "#f00")(.2), "#6b6890"); - assert.strictEqual(d3.interpolateRgb("steelblue", d3.rgb(255, 0, 0))(.6), "#b53448"); - }, - "parses d3.hsl input": function(d3) { - assert.strictEqual(d3.interpolateRgb(d3.hsl("steelblue"), "#f00")(.2), "#6b6890"); - assert.strictEqual(d3.interpolateRgb("steelblue", d3.hsl(0, 1, .5))(.6), "#b53448"); - }, - "interpolates in RGB color space": function(d3) { - assert.strictEqual(d3.interpolateRgb("steelblue", "#f00")(.2), "#6b6890"); - }, - "outputs an RGB string": function(d3) { - assert.strictEqual(d3.interpolateRgb("steelblue", "#f00")(.2), "#6b6890"); - } - } -}); - -suite.export(module); diff --git a/test/interpolate/round-test.js b/test/interpolate/round-test.js deleted file mode 100644 index 98fad587ec0f86..00000000000000 --- a/test/interpolate/round-test.js +++ /dev/null @@ -1,17 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateRound"); - -suite.addBatch({ - "interpolateRound": { - topic: load("interpolate/round").expression("d3.interpolateRound"), - "interpolates integers": function(interpolate) { - assert.strictEqual(interpolate(2, 12)(.456), 7); - assert.strictEqual(interpolate(2, 12)(.678), 9); - } - } -}); - -suite.export(module); diff --git a/test/interpolate/string-test.js b/test/interpolate/string-test.js deleted file mode 100644 index 5e7b106705201b..00000000000000 --- a/test/interpolate/string-test.js +++ /dev/null @@ -1,43 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.interpolateString"); - -suite.addBatch({ - "interpolateString": { - topic: load("interpolate/string").expression("d3.interpolateString"), - "interpolates matching numbers in both strings": function(interpolate) { - assert.strictEqual(interpolate(" 10/20 30", "50/10 100 ")(.2), "18/18 44 "); - assert.strictEqual(interpolate(" 10/20 30", "50/10 100 ")(.4), "26/16 58 "); - }, - "coerces objects to strings": function(interpolate) { - assert.strictEqual(interpolate({toString: function() { return "2px"; }}, {toString: function() { return "12px"; }})(.4), "6px"); - }, - "preserves non-numbers in string b": function(interpolate) { - assert.strictEqual(interpolate(" 10/20 30", "50/10 foo ")(.2), "18/18 foo "); - assert.strictEqual(interpolate(" 10/20 30", "50/10 foo ")(.4), "26/16 foo "); - }, - "preserves non-matching numbers in string b": function(interpolate) { - assert.strictEqual(interpolate(" 10/20 foo", "50/10 100 ")(.2), "18/18 100 "); - assert.strictEqual(interpolate(" 10/20 bar", "50/10 100 ")(.4), "26/16 100 "); - }, - "preserves equal-value numbers in both strings": function(interpolate) { - assert.strictEqual(interpolate(" 10/20 100 20", "50/10 100, 20 ")(.2), "18/18 100, 20 "); - assert.strictEqual(interpolate(" 10/20 100 20", "50/10 100, 20 ")(.4), "26/16 100, 20 "); - }, - "interpolates decimal notation correctly": function(interpolate) { - assert.strictEqual(interpolate("1.", "2.")(.5), "1.5"); - }, - "interpolates exponent notation correctly": function(interpolate) { - assert.strictEqual(interpolate("1e+3", "1e+4")(.5), "5500"); - assert.strictEqual(interpolate("1e-3", "1e-4")(.5), "0.00055"); - assert.strictEqual(interpolate("1.e-3", "1.e-4")(.5), "0.00055"); - assert.strictEqual(interpolate("-1.e-3", "-1.e-4")(.5), "-0.00055"); - assert.strictEqual(interpolate("+1.e-3", "+1.e-4")(.5), "0.00055"); - assert.strictEqual(interpolate(".1e-2", ".1e-3")(.5), "0.00055"); - } - } -}); - -suite.export(module); diff --git a/test/layout/chord-test.js b/test/layout/chord-test.js deleted file mode 100644 index f2627bd4fed05e..00000000000000 --- a/test/layout/chord-test.js +++ /dev/null @@ -1,164 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.chord"); - -suite.addBatch({ - "chord": { - topic: load("layout/chord").expression("d3.layout.chord"), - "of a simple matrix": { - topic: function(chord) { - return chord() - .padding(.05) - .sortSubgroups(function(a, b) { return b - a; }) - .matrix([ - [11975, 5871, 8916, 2868], - [ 1951, 10048, 2060, 6171], - [ 8010, 16145, 8090, 8045], - [ 1013, 990, 940, 6907] - ]); - }, - "computes chord groups": function(chord) { - var groups = chord.groups(); - assert.equal(groups.length, 4); - - assert.equal(groups[0].index, 0); - assert.inDelta(groups[0].startAngle, 0.0000000000000000, 1e-6); - assert.inDelta(groups[0].endAngle, 1.8024478065173115, 1e-6); - assert.inDelta(groups[0].value, 29630, 1e-6); - - assert.equal(groups[1].index, 1); - assert.inDelta(groups[1].startAngle, 1.8524478065173116, 1e-6); - assert.inDelta(groups[1].endAngle, 3.0830761941597418, 1e-6); - assert.inDelta(groups[1].value, 20230, 1e-6); - - assert.equal(groups[2].index, 2); - assert.inDelta(groups[2].startAngle, 3.1330761941597416, 1e-6); - assert.inDelta(groups[2].endAngle, 5.583991554422396, 1e-6); - assert.inDelta(groups[2].value, 40290, 1e-6); - - assert.equal(groups[3].index, 3); - assert.inDelta(groups[3].startAngle, 5.6339915544223960, 1e-6); - assert.inDelta(groups[3].endAngle, 6.233185307179585, 1e-6); - assert.inDelta(groups[3].value, 9850, 1e-6); - }, - "computes chords": function(chord) { - var chords = chord.chords(); - assert.equal(chords.length, 10); - - assert.equal(chords[0].source.index, 0); - assert.equal(chords[0].source.subindex, 0); - assert.inDelta(chords[0].source.startAngle, 0, 1e-6); - assert.inDelta(chords[0].source.endAngle, 0.7284614405347555, 1e-6); - assert.equal(chords[0].source.value, 11975); - assert.equal(chords[0].target.index, 0); - assert.equal(chords[0].target.subindex, 0); - assert.inDelta(chords[0].target.startAngle, 0, 1e-6); - assert.inDelta(chords[0].target.endAngle, 0.7284614405347555, 1e-6); - assert.equal(chords[0].target.value, 11975); - - assert.equal(chords[1].source.index, 0); - assert.equal(chords[1].source.subindex, 1); - assert.inDelta(chords[1].source.startAngle, 1.2708382425228875, 1e-6); - assert.inDelta(chords[1].source.endAngle, 1.6279820519074009, 1e-6); - assert.equal(chords[1].source.value, 5871); - assert.equal(chords[1].target.index, 1); - assert.equal(chords[1].target.subindex, 0); - assert.inDelta(chords[1].target.startAngle, 2.964393248816668, 1e-6); - assert.inDelta(chords[1].target.endAngle, 3.0830761941597418, 1e-6); - assert.equal(chords[1].target.value, 1951); - - assert.equal(chords[2].source.index, 0); - assert.equal(chords[2].source.subindex, 2); - assert.inDelta(chords[2].source.startAngle, 0.7284614405347555, 1e-6); - assert.inDelta(chords[2].source.endAngle, 1.2708382425228875, 1e-6); - assert.equal(chords[2].source.value, 8916); - assert.equal(chords[2].target.index, 2); - assert.equal(chords[2].target.subindex, 0); - assert.inDelta(chords[2].target.startAngle, 5.0967284113173115, 1e-6); - assert.inDelta(chords[2].target.endAngle, 5.583991554422396, 1e-6); - assert.equal(chords[2].target.value, 8010); - - assert.equal(chords[3].source.index, 0); - assert.equal(chords[3].source.subindex, 3); - assert.inDelta(chords[3].source.startAngle, 1.6279820519074009, 1e-6); - assert.inDelta(chords[3].source.endAngle, 1.8024478065173115, 1e-6); - assert.equal(chords[3].source.value, 2868); - assert.equal(chords[3].target.index, 3); - assert.equal(chords[3].target.subindex, 0); - assert.inDelta(chords[3].target.startAngle, 6.05415716358929, 1e-6); - assert.inDelta(chords[3].target.endAngle, 6.115779830751019, 1e-6); - assert.equal(chords[3].target.value, 1013); - - assert.equal(chords[4].source.index, 1); - assert.equal(chords[4].source.subindex, 1); - assert.inDelta(chords[4].source.startAngle, 1.8524478065173116, 1e-6); - assert.inDelta(chords[4].source.endAngle, 2.4636862661827164, 1e-6); - assert.equal(chords[4].source.value, 10048); - assert.equal(chords[4].target.index, 1); - assert.equal(chords[4].target.subindex, 1); - assert.inDelta(chords[4].target.startAngle, 1.8524478065173116, 1e-6); - assert.inDelta(chords[4].target.endAngle, 2.4636862661827164, 1e-6); - assert.equal(chords[4].target.value, 10048); - - assert.equal(chords[5].source.index, 2); - assert.equal(chords[5].source.subindex, 1); - assert.inDelta(chords[5].source.startAngle, 3.1330761941597416, 1e-6); - assert.inDelta(chords[5].source.endAngle, 4.1152064620038855, 1e-6); - assert.equal(chords[5].source.value, 16145); - assert.equal(chords[5].target.index, 1); - assert.equal(chords[5].target.subindex, 2); - assert.inDelta(chords[5].target.startAngle, 2.8390796314887687, 1e-6); - assert.inDelta(chords[5].target.endAngle, 2.964393248816668, 1e-6); - assert.equal(chords[5].target.value, 2060); - - assert.equal(chords[6].source.index, 1); - assert.equal(chords[6].source.subindex, 3); - assert.inDelta(chords[6].source.startAngle, 2.4636862661827164, 1e-6); - assert.inDelta(chords[6].source.endAngle, 2.8390796314887687, 1e-6); - assert.equal(chords[6].source.value, 6171); - assert.equal(chords[6].target.index, 3); - assert.equal(chords[6].target.subindex, 1); - assert.inDelta(chords[6].target.startAngle, 6.115779830751019, 1e-6); - assert.inDelta(chords[6].target.endAngle, 6.176003365292097, 1e-6); - assert.equal(chords[6].target.value, 990); - - assert.equal(chords[7].source.index, 2); - assert.equal(chords[7].source.subindex, 2); - assert.inDelta(chords[7].source.startAngle, 4.1152064620038855, 1e-6); - assert.inDelta(chords[7].source.endAngle, 4.607336153354714, 1e-6); - assert.equal(chords[7].source.value, 8090); - assert.equal(chords[7].target.index, 2); - assert.equal(chords[7].target.subindex, 2); - assert.inDelta(chords[7].target.startAngle, 4.1152064620038855, 1e-6); - assert.inDelta(chords[7].target.endAngle, 4.607336153354714, 1e-6); - assert.equal(chords[7].target.value, 8090); - - assert.equal(chords[8].source.index, 2); - assert.equal(chords[8].source.subindex, 3); - assert.inDelta(chords[8].source.startAngle, 4.607336153354714, 1e-6); - assert.inDelta(chords[8].source.endAngle, 5.0967284113173115, 1e-6); - assert.equal(chords[8].source.value, 8045); - assert.equal(chords[8].target.index, 3); - assert.equal(chords[8].target.subindex, 2); - assert.inDelta(chords[8].target.startAngle, 6.176003365292097, 1e-6); - assert.inDelta(chords[8].target.endAngle, 6.233185307179585, 1e-6); - assert.equal(chords[8].target.value, 940); - - assert.equal(chords[9].source.index, 3); - assert.equal(chords[9].source.subindex, 3); - assert.inDelta(chords[9].source.startAngle, 5.633991554422396, 1e-6); - assert.inDelta(chords[9].source.endAngle, 6.05415716358929, 1e-6); - assert.equal(chords[9].source.value, 6907); - assert.equal(chords[9].target.index, 3); - assert.equal(chords[9].target.subindex, 3); - assert.inDelta(chords[9].target.startAngle, 5.633991554422396, 1e-6); - assert.inDelta(chords[9].target.endAngle, 6.05415716358929, 1e-6); - assert.equal(chords[9].target.value, 6907); - } - } - } -}); - -suite.export(module); diff --git a/test/layout/cluster-test.js b/test/layout/cluster-test.js deleted file mode 100644 index caa2747db58232..00000000000000 --- a/test/layout/cluster-test.js +++ /dev/null @@ -1,44 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.cluster"); - -suite.addBatch({ - "cluster": { - topic: load("layout/cluster").expression("d3.layout.cluster"), - "can handle an empty children array": function(cluster) { - var c = cluster(); - assert.deepEqual(c.nodes({value: 1, children: [{value: 1, children: []}, {value: 1}]}).map(layout), [ - {value: 1, depth: 0, x: 0.5, y: 0}, - {value: 1, depth: 1, x: 0.25, y: 1}, - {value: 1, depth: 1, x: 0.75, y: 1} - ]); - }, - "can handle zero-valued nodes": function(cluster) { - var c = cluster(); - assert.deepEqual(c.nodes({value: 0, children: [{value: 0}, {value: 1}]}).map(layout), [ - {value: 0, depth: 0, x: 0.5, y: 0}, - {value: 0, depth: 1, x: 0.25, y: 1}, - {value: 1, depth: 1, x: 0.75, y: 1} - ]); - }, - "can handle a single node": function(cluster) { - var c = cluster(); - assert.deepEqual(c.nodes({value: 0}).map(layout), [ - {value: 0, depth: 0, x: 0.5, y: 0} - ]); - } - } -}); - -function layout(node) { - return { - value: node.value, - depth: node.depth, - x: node.x, - y: node.y - }; -} - -suite.export(module); diff --git a/test/layout/force-test.js b/test/layout/force-test.js deleted file mode 100644 index a4b5870838a840..00000000000000 --- a/test/layout/force-test.js +++ /dev/null @@ -1,119 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.force"); - -suite.addBatch({ - "force": { - topic: load("layout/force").expression("d3.layout.force").document(), - - "default instance": { - topic: function(force) { - return force(); - }, - - "friction": { - "defaults to .9": function(f) { - assert.equal(f.friction(), .9); - }, - "can be a number": function(f) { - f.friction(.5); - assert.equal(f.friction(), .5); - }, - "coerces to a number": function(f) { - f.friction(".5"); - assert.strictEqual(f.friction(), .5); - } - }, - - "gravity": { - "defaults to .1": function(f) { - assert.equal(f.gravity(), .1); - }, - "can be a number": function(f) { - f.gravity(.5); - assert.equal(f.gravity(), .5); - }, - "coerces to a number": function(f) { - f.gravity(".5"); - assert.strictEqual(f.gravity(), .5); - } - }, - - "theta": { - "defaults to .8": function(f) { - assert.equal(f.theta(), .8); - }, - "can be a number": function(f) { - f.theta(.5); - assert.equal(f.theta(), .5); - }, - "coerces to a number": function(f) { - f.theta(".5"); - assert.strictEqual(f.theta(), .5); - } - }, - - "charge": { - "defaults to -30": function(f) { - assert.equal(f.charge(), -30); - }, - "can be a number": function(f) { - f.charge(-40); - assert.equal(f.charge(), -40); - }, - "can be a function": function(f) { // TODO expose the computed value? - f.charge(foo); - assert.equal(f.charge(), foo); - }, - "coerces to a number": function(f) { - f.charge("-40"); - assert.strictEqual(f.charge(), -40); - } - }, - - "linkDistance": { - "defaults to 20": function(f) { - assert.equal(f.linkDistance(), 20); - }, - "can be a number": function(f) { - f.linkDistance(40); - assert.equal(f.linkDistance(), 40); - }, - "can be a function": function(f) { // TODO expose the computed value? - f.linkDistance(foo); - assert.equal(f.linkDistance(), foo); - }, - "coerces to a number": function(f) { - f.linkDistance("40"); - assert.strictEqual(f.linkDistance(), 40); - } - }, - - "linkStrength": { - "defaults to 1": function(f) { - assert.equal(f.linkStrength(), 1); - }, - "can be a number": function(f) { - f.linkStrength(.5); - assert.equal(f.linkStrength(), .5); - }, - "can be a function": function(f) { // TODO expose the computed value? - f.linkStrength(foo); - assert.equal(f.linkStrength(), foo); - }, - "coerces to a number": function(f) { - f.linkStrength(".5"); - assert.strictEqual(f.linkStrength(), .5); - } - } - } - } -}); - -function foo(d) { - return d.foo; -} - -suite.export(module); diff --git a/test/layout/hierarchy-test.js b/test/layout/hierarchy-test.js deleted file mode 100644 index a911ece2e5e4b0..00000000000000 --- a/test/layout/hierarchy-test.js +++ /dev/null @@ -1,27 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.hierarchy"); - -suite.addBatch({ - "hierarchy": { - topic: load("layout/treemap").expression("d3.layout.treemap"), // hierarchy is abstract, so test a subclass - "doesn't overwrite the value of a node that has an empty children array": function(hierarchy) { - var h = hierarchy(), - nodes = h.sticky(true).nodes({value: 1, children: []}); - assert.equal(nodes[0].value, 1); - h.nodes(nodes[0]); - assert.equal(nodes[0].value, 1); - }, - "a valueless node that has an empty children array gets a value of 0": function(hierarchy) { - var h = hierarchy(), - nodes = h.sticky(true).nodes({children: []}); - assert.equal(nodes[0].value, 0); - h.nodes(nodes[0]); - assert.equal(nodes[0].value, 0); - } - } -}); - -suite.export(module); diff --git a/test/layout/histogram-test.js b/test/layout/histogram-test.js deleted file mode 100644 index 004bcdcd39582f..00000000000000 --- a/test/layout/histogram-test.js +++ /dev/null @@ -1,92 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.histogram"); - -suite.addBatch({ - "histogram": { - topic: load("layout/histogram").expression("d3.layout.histogram"), - "defaults to frequencies": function(histogram) { - var h = histogram(); - assert.deepEqual(h([0,0,0,1,2,2]).map(elements), [[0, 0, 0], [], [1], [2, 2]]); - }, - "each bin contains the matching source elements": function(histogram) { - var h = histogram(); - assert.deepEqual(h([0,0,0,1,2,2]).map(elements), [[0, 0, 0], [], [1], [2, 2]]); - }, - "each bin also has defined x, y and dx properties": function(histogram) { - var h = histogram(); - assert.deepEqual(h([0,0,0,1,2,2]).map(metadata), [ - {x: 0, y: 3, dx: 0.5}, - {x: 0.5, y: 0, dx: 0.5}, - {x: 1, y: 1, dx: 0.5}, - {x: 1.5, y: 2, dx: 0.5} - ]); - }, - "can output frequencies": function(histogram) { - var h = histogram().frequency(true); - assert.deepEqual(h([0,0,0,1,2,2]).map(metadata), [ - {x: 0, y: 3, dx: 0.5}, - {x: 0.5, y: 0, dx: 0.5}, - {x: 1, y: 1, dx: 0.5}, - {x: 1.5, y: 2, dx: 0.5} - ]); - }, - "can output probabilities": function(histogram) { - var h = histogram().frequency(false); - assert.deepEqual(h([0,0,0,1,2,2]).map(metadata), [ - {x: 0, y: 3/6, dx: 0.5}, - {x: 0.5, y: 0, dx: 0.5}, - {x: 1, y: 1/6, dx: 0.5}, - {x: 1.5, y: 2/6, dx: 0.5} - ]); - }, - "can specify number of bins": function(histogram) { - var h = histogram().bins(2); - assert.deepEqual(h([0,0,0,1,2,2]).map(elements), [ - [0, 0, 0], - [1, 2, 2] - ]); - assert.deepEqual(h([0,0,0,1,2,2]).map(metadata), [ - {x: 0, y: 3, dx: 1}, - {x: 1, y: 3, dx: 1} - ]); - }, - "can specify bin thresholds": function(histogram) { - var h = histogram().bins([0,1,2,3]); - assert.deepEqual(h([0,0,0,1,2,2]).map(elements), [ - [0, 0, 0], - [1], - [2, 2] - ]); - assert.deepEqual(h([0,0,0,1,2,2]).map(metadata), [ - {x: 0, y: 3, dx: 1}, - {x: 1, y: 1, dx: 1}, - {x: 2, y: 2, dx: 1} - ]); - }, - "returns the empty array with fewer than two bins": function(histogram) { - var h = histogram().bins([1]); - assert.deepEqual(h([0]), []); - var h = histogram().bins([]); - assert.deepEqual(h([0]), []); - } - } -}); - -function elements(bin) { - var array = [], i = -1, n = bin.length; - while (++i < n) array.push(bin[i]); - return array; -} - -function metadata(bin) { - var metadata = {}; - if ("x" in bin) metadata.x = bin.x; - if ("y" in bin) metadata.y = bin.y; - if ("dx" in bin) metadata.dx = bin.dx; - return metadata; -} - -suite.export(module); diff --git a/test/layout/pack-test.js b/test/layout/pack-test.js deleted file mode 100644 index 5c39ea5bbf9e55..00000000000000 --- a/test/layout/pack-test.js +++ /dev/null @@ -1,129 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.pack"); - -suite.addBatch({ - "pack": { - topic: load("layout/pack").expression("d3.layout.pack"), - "can handle an empty children array": function(pack) { - var p = pack(); - assert.deepEqual(p.nodes({children: [{children: []}, {value: 1}]}).map(layout), [ - {value: 1, depth: 0, x: 0.5, y: 0.5, r: 0.5}, - {value: 0, depth: 1, x: 0.0, y: 0.5, r: 0.0}, - {value: 1, depth: 1, x: 0.5, y: 0.5, r: 0.5} - ]); - }, - "can handle zero-valued nodes": function(pack) { - var p = pack(); - assert.deepEqual(p.nodes({children: [{value: 0}, {value: 1}]}).map(layout), [ - {value: 1, depth: 0, x: 0.5, y: 0.5, r: 0.5}, - {value: 0, depth: 1, x: 0.0, y: 0.5, r: 0.0}, - {value: 1, depth: 1, x: 0.5, y: 0.5, r: 0.5} - ]); - }, - "can handle small nodes": function(pack) { - assert.deepEqual(pack().sort(null).nodes({children: [ - {value: .01}, - {value: 2}, - {value: 2}, - {value: 1} - ]}).map(layout), [ - {y: 0.5, x: 0.5, value: 5.01, r: 0.5, depth: 0}, - {y: 0.5084543199854831, x: 0.4682608366855136, value: 0.01, r: 0.016411496513964046, depth: 1}, - {y: 0.5084543199854831, x: 0.7167659426883449, value: 2, r: 0.23209360948886723, depth: 1}, - {y: 0.34256315498862167, x: 0.2832340573116551, value: 2, r: 0.23209360948886723, depth: 1}, - {y: 0.7254154893606051, x: 0.38524055061025186, value: 1, r: 0.16411496513964044, depth: 1} - ]); - assert.deepEqual(pack().sort(null).nodes({children: [ - {value: 2}, - {value: 2}, - {value: 1}, - {value: .01} - ]}).map(layout), [ - {y: 0.5, x: 0.5, value: 5.01, r: 0.5, depth: 0}, - {y: 0.6274712284943809, x: 0.26624891409386664, value: 2, r: 0.23375108590613333, depth: 1}, - {y: 0.6274712284943809, x: 0.7337510859061334, value: 2, r: 0.23375108590613333, depth: 1}, - {y: 0.30406466355343187, x: 0.5, value: 1, r: 0.1652869779539461, depth: 1}, - {y: 0.3878967195987758, x: 0.3386645534068854, value: 0.01, r: 0.01652869779539461, depth: 1} - ]); - }, - "can handle residual floating point error": function(pack) { - var p = pack(); - var result = p.nodes({children: [ - {value: 0.005348322447389364}, - {value: 0.8065882022492588}, - {value: 0} - ]}).map(layout); - assert.isFalse(result.map(function(d) { return d.depth; }).some(isNaN)); - assert.isFalse(result.map(function(d) { return d.value; }).some(isNaN)); - assert.isFalse(result.map(function(d) { return d.x; }).some(isNaN)); - assert.isFalse(result.map(function(d) { return d.y; }).some(isNaN)); - assert.isFalse(result.map(function(d) { return d.r; }).some(isNaN)); - }, - "avoids coincident circles": function(pack) { - var p = pack(); - var result = p({children: [ - {children: [{value: 17010}, {value: 5842}, {value: 0}, {value: 0}]}, - {children: [ - {children: [{value: 721}, {value: 4294}, {value: 9800}, {value: 1314}, {value: 2220}]}, - {value: 1759}, {value: 2165}, {value: 586}, {value: 3331}, {value: 772}, {value: 3322} - ]} - ]}).map(layout); - result.sort(function(a, b) { - return a.x < b.x && a.y < b.y ? -1 : 1; - }); - assert.isFalse(result.slice(1).some(function(d, i) { - return d.x === result[i].x && d.y === result[i].y && d.value > 0; - })); - }, - "radius defaults to automatic scaling": function(pack) { - assert.equal(pack().radius(), null); - }, - "radius can be specified using a custom function of value": function(pack) { - var r = function(value) { return Math.sqrt(value) * 10; }, - p = pack().radius(r); - assert.strictEqual(p.radius(), r); - assert.deepEqual(p.nodes({children: [{value: 1}]}).map(layout), [ - {value: 1, depth: 0, x: 0.5, y: 0.5, r: 10}, - {value: 1, depth: 1, x: 0.5, y: 0.5, r: 10} - ]); - }, - "radius can be specified as a constant": function(pack) { - var p = pack().radius(5); - assert.equal(p.radius(), 5); - assert.deepEqual(p.nodes({children: [{value: 1}]}).map(layout), [ - {value: 1, depth: 0, x: 0.5, y: 0.5, r: 5}, - {value: 1, depth: 1, x: 0.5, y: 0.5, r: 5} - ]); - }, - "radius constant value is coerced to a number": function(pack) { - var p = pack().radius("5"); - assert.equal(p.radius(), 5); - assert.deepEqual(p.nodes({children: [{value: 1}]}).map(layout), [ - {value: 1, depth: 0, x: 0.5, y: 0.5, r: 5}, - {value: 1, depth: 1, x: 0.5, y: 0.5, r: 5} - ]); - }, - "radius function value is coerced to a number": function(pack) { - var p = pack().radius(function() { return "5"; }); - assert.deepEqual(p.nodes({children: [{value: 1}]}).map(layout), [ - {value: 1, depth: 0, x: 0.5, y: 0.5, r: 5}, - {value: 1, depth: 1, x: 0.5, y: 0.5, r: 5} - ]); - } - } -}); - -function layout(node) { - return { - value: node.value, - depth: node.depth, - r: node.r, - x: node.x, - y: node.y - }; -} - -suite.export(module); diff --git a/test/layout/partition-test.js b/test/layout/partition-test.js deleted file mode 100644 index e7aba2561a42ad..00000000000000 --- a/test/layout/partition-test.js +++ /dev/null @@ -1,45 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.partition"); - -suite.addBatch({ - "partition": { - topic: load("layout/partition").expression("d3.layout.partition"), - "ignores zero values": function(partition) { - var p = partition().size([3, 3]); - assert.deepEqual(p.nodes({children: [{value: 1}, {value: 0}, {value: 2}, {children: [{value: 0}, {value: 0}]}]}).map(metadata), [ - {x: 0, y: 0, dx: 3, dy: 1}, - {x: 2, y: 1, dx: 1, dy: 1}, - {x: 3, y: 1, dx: 0, dy: 1}, - {x: 0, y: 1, dx: 2, dy: 1}, - {x: 3, y: 1, dx: 0, dy: 1}, - {x: 3, y: 2, dx: 0, dy: 1}, - {x: 3, y: 2, dx: 0, dy: 1} - ]); - }, - "can handle an empty children array": function(partition) { - var p = partition(); - assert.deepEqual(p.nodes({children: []}).map(metadata), [ - {x: 0, y: 0, dx: 1, dy: 1} - ]); - assert.deepEqual(p.nodes({children: [{children: []}, {value: 1}]}).map(metadata), [ - {x: 0, y: 0, dx: 1, dy: 0.5}, - {x: 1, y: 0.5, dx: 0, dy: 0.5}, - {x: 0, y: 0.5, dx: 1, dy: 0.5} - ]); - } - } -}); - -function metadata(node) { - var metadata = {}; - if ("x" in node) metadata.x = node.x; - if ("y" in node) metadata.y = node.y; - if ("dx" in node) metadata.dx = node.dx; - if ("dy" in node) metadata.dy = node.dy; - return metadata; -} - -suite.export(module); diff --git a/test/layout/pie-test.js b/test/layout/pie-test.js deleted file mode 100644 index f4fb2f18c1b9b7..00000000000000 --- a/test/layout/pie-test.js +++ /dev/null @@ -1,24 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.pie"); - -suite.addBatch({ - "pie": { - topic: load("layout/pie").expression("d3.layout.pie"), - "arcs are in same order as original data": function(pie) { - var p = pie(); - assert.deepEqual(p([5, 30, 15]).map(function(d) { return d.data; }), [ - 5, 30, 15 - ]); - assert.deepEqual(p([ - 84, 90, 48, 61, 58, 8, 6, 31, 45, 18 - ]).map(function(d) { return d.data; }), [ - 84, 90, 48, 61, 58, 8, 6, 31, 45, 18 - ]); - } - } -}); - -suite.export(module); diff --git a/test/layout/tree-test.js b/test/layout/tree-test.js deleted file mode 100644 index cc5070e3864cf5..00000000000000 --- a/test/layout/tree-test.js +++ /dev/null @@ -1,45 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.tree"); - -suite.addBatch({ - "tree": { - topic: load("layout/tree").expression("d3.layout.tree"), - "can handle an empty children array": function(tree) { - var t = tree(); - assert.deepEqual(t.nodes({children: []}).map(layout), [ - {depth: 0, x: 0.5, y: 0} - ]); - assert.deepEqual(t.nodes({children: [ - {children: []}, - {children: [{}]}, - {children: [{}]} - ]}).map(layout), [ - {depth: 0, x: .5, y: 0}, - {depth: 1, x: .125, y: 0.5}, - {depth: 1, x: .375, y: 0.5}, - {depth: 2, x: .375, y: 1}, - {depth: 1, x: .875, y: 0.5}, - {depth: 2, x: .875, y: 1} - ]); - }, - "can handle a single node": function(tree) { - var t = tree(); - assert.deepEqual(t.nodes({value: 0}).map(layout), [ - {depth: 0, x: 0.5, y: 0} - ]); - } - } -}); - -function layout(node) { - return { - depth: node.depth, - x: node.x, - y: node.y - }; -} - -suite.export(module); diff --git a/test/layout/treemap-test.js b/test/layout/treemap-test.js deleted file mode 100644 index a25b37f2a48521..00000000000000 --- a/test/layout/treemap-test.js +++ /dev/null @@ -1,181 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.layout.treemap"); - -suite.addBatch({ - "treemap": { - topic: load("layout/treemap").expression("d3.layout.treemap"), - "outputs a squarified treemap": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 0, y: 833, dx: 1000, dy: 167}, - {x: 600, y: 0, dx: 400, dy: 833}, - {x: 0, y: 0, dx: 600, dy: 833}, - {x: 0, y: 555, dx: 600, dy: 278}, - {x: 0, y: 0, dx: 600, dy: 555} - ]); - }, - "sorts by value by default": function(treemap) { - var t = treemap().size([1000, 1000]); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 0, y: 0, dx: 333, dy: 500}, - {x: 333, y: 0, dx: 667, dy: 500}, - {x: 0, y: 500, dx: 1000, dy: 500}, - {x: 0, y: 500, dx: 333, dy: 500}, - {x: 333, y: 500, dx: 667, dy: 500} - ]); - }, - "ignores zero values": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 0}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 0, y: 833, dx: 1000, dy: 167}, - {x: 1000, y: 0, dx: 0, dy: 833}, - {x: 600, y: 0, dx: 400, dy: 833}, - {x: 0, y: 0, dx: 600, dy: 833}, - {x: 0, y: 555, dx: 600, dy: 278}, - {x: 0, y: 0, dx: 600, dy: 555} - ]); - }, - "ignores NaN values": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: NaN}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 0, y: 833, dx: 1000, dy: 167}, - {x: 1000, y: 0, dx: 0, dy: 833}, - {x: 600, y: 0, dx: 400, dy: 833}, - {x: 0, y: 0, dx: 600, dy: 833}, - {x: 0, y: 555, dx: 600, dy: 278}, - {x: 0, y: 0, dx: 600, dy: 555} - ]); - }, - "does not overflow empty size": function(treemap) { - var t = treemap().size([0, 0]).sort(null); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 0, dy: 0}, - {x: 0, y: 0, dx: 0, dy: 0}, - {x: 0, y: 0, dx: 0, dy: 0}, - {x: 0, y: 0, dx: 0, dy: 0}, - {x: 0, y: 0, dx: 0, dy: 0}, - {x: 0, y: 0, dx: 0, dy: 0} - ]); - }, - "can specify padding as a number": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null).padding(1); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 1, y: 833, dx: 998, dy: 166}, - {x: 600, y: 1, dx: 399, dy: 832}, - {x: 1, y: 1, dx: 599, dy: 832}, - {x: 2, y: 555, dx: 597, dy: 277}, - {x: 2, y: 2, dx: 597, dy: 553} - ]); - }, - "can specify padding as an array": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null).padding([1,2,3,4]); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 4, y: 831, dx: 994, dy: 166}, - {x: 600, y: 1, dx: 398, dy: 830}, - {x: 4, y: 1, dx: 596, dy: 830}, - {x: 8, y: 553, dx: 590, dy: 275}, - {x: 8, y: 2, dx: 590, dy: 551} - ]); - }, - "can specify padding as null": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null).padding(null); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 0, y: 833, dx: 1000, dy: 167}, - {x: 600, y: 0, dx: 400, dy: 833}, - {x: 0, y: 0, dx: 600, dy: 833}, - {x: 0, y: 555, dx: 600, dy: 278}, - {x: 0, y: 0, dx: 600, dy: 555} - ]); - }, - "can specify padding as a function that returns a number": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null).padding(function(d) { return d.depth; }); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 0, y: 833, dx: 1000, dy: 167}, - {x: 600, y: 0, dx: 400, dy: 833}, - {x: 0, y: 0, dx: 600, dy: 833}, - {x: 1, y: 555, dx: 598, dy: 277}, - {x: 1, y: 1, dx: 598, dy: 554} - ]); - }, - "can specify padding as a function that returns an array": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null).padding(function(d) { return [d.depth,2,3,4]; }); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 4, y: 831, dx: 994, dy: 166}, - {x: 600, y: 0, dx: 398, dy: 831}, - {x: 4, y: 0, dx: 596, dy: 831}, - {x: 8, y: 552, dx: 590, dy: 276}, - {x: 8, y: 1, dx: 590, dy: 551} - ]); - }, - "can specify padding as a function that returns null": function(treemap) { - var t = treemap().size([1000, 1000]).sort(null).padding(function(d) { return d.depth & 1 ? null : 1; }); - assert.deepEqual(t.nodes({children: [{value: 1}, {value: 2}, {children: [{value: 1}, {value: 2}]}]}).map(layout), [ - {x: 0, y: 0, dx: 1000, dy: 1000}, - {x: 1, y: 833, dx: 998, dy: 166}, - {x: 600, y: 1, dx: 399, dy: 832}, - {x: 1, y: 1, dx: 599, dy: 832}, - {x: 1, y: 556, dx: 599, dy: 277}, - {x: 1, y: 1, dx: 599, dy: 555} - ]); - }, - "no negatively sized rectangles": function(treemap) { - var t = treemap().size([615, 500]).sort(function(a, b) { return a.value - b.value; }).padding(29), - data = [1, 9, 3, 15, 44, 28, 32, 41, 50, 60, 64, 75, 76, 84, 88, 100, 140, 142, 363, 657, 670, 822, 1173, 1189], - nodes = t.nodes({children: data.map(function(d) { return {value: d}; })}).map(layout); - assert.equal(nodes.filter(function(n) { return n.dx < 0 || n.dy < 0; }).length, 0); - }, - "no overhanging rectangles": function(treemap) { - var t = treemap().size([100, 100]).sort(function(a, b) { return a.value - b.value; }), - data = [0, 0, 81681.85, 370881.9, 0, 0, 0, 255381.59, 0, 0, 0, 0, 0, 0, 0, 125323.95, 0, 0, 0, 186975.07, 185707.05, 267370.93, 0], - nodes = t.nodes({children: data.map(function(d) { return {value: d}; })}).map(layout); - assert.equal(nodes.filter(function(n) { return n.dx < 0 || n.dy < 0 || n.x + n.dx > 100 || n.y + n.dy > 100; }).length, 0); - }, - "can handle an empty children array": function(treemap) { - assert.deepEqual(treemap().nodes({children: []}).map(layout), [ - {x: 0, y: 0, dx: 1, dy: 1} - ]); - assert.deepEqual(treemap().nodes({children: [{children: []}, {value: 1}]}).map(layout), [ - {x: 0, y: 0, dx: 1, dy: 1}, - {x: 0, y: 0, dx: 0, dy: 1}, - {x: 0, y: 0, dx: 1, dy: 1} - ]); - }, - "slice-dice": function(treemap) { - assert.deepEqual(treemap().size([100, 10]).mode("slice-dice").nodes({children: [ - {children: [{value: 1}, {value: 1}]}, - {children: [{value: 1}, {value: 1}]} - ]}).map(layout), [ - {x: 0, y: 0, dx: 100, dy: 10}, - {x: 50, y: 0, dx: 50, dy: 10}, - {x: 50, y: 5, dx: 50, dy: 5}, - {x: 50, y: 0, dx: 50, dy: 5}, - {x: 0, y: 0, dx: 50, dy: 10}, - {x: 0, y: 5, dx: 50, dy: 5}, - {x: 0, y: 0, dx: 50, dy: 5} - ]); - } - } -}); - -function layout(node) { - return { - x: node.x, - y: node.y, - dx: node.dx, - dy: node.dy - }; -} - -suite.export(module); diff --git a/test/load.js b/test/load.js deleted file mode 100644 index 269bb2778e56eb..00000000000000 --- a/test/load.js +++ /dev/null @@ -1,58 +0,0 @@ -process.env.TZ = "America/Los_Angeles"; - -var smash = require("smash"), - jsdom = require("jsdom"); - -require("./XMLHttpRequest"); - -module.exports = function() { - var files = [].slice.call(arguments).map(function(d) { return "src/" + d; }), - expression = "d3", - sandbox = {console: console, Date: Date}; // so we can use deepEqual in tests - - files.unshift("src/start"); - files.push("src/end"); - - function topic() { - var callback = this.callback; - smash.load(files, expression, sandbox, function(error, result) { - if (error) console.trace(error.stack); - callback(error, result); - }); - } - - topic.expression = function(_) { - expression = _; - return topic; - }; - - topic.document = function(_) { - var document = jsdom.jsdom(""); - - // Monkey-patch createRange support to JSDOM. - document.createRange = function() { - return { - selectNode: function() {}, - createContextualFragment: jsdom.jsdom - }; - }; - - sandbox = { - console: console, - XMLHttpRequest: XMLHttpRequest, - document: document, - window: document.createWindow(), - setTimeout: setTimeout, - clearTimeout: clearTimeout, - Date: Date // so we can override Date.now in tests, and use deepEqual - }; - - return topic; - }; - - return topic; -}; - -process.on("uncaughtException", function(e) { - console.trace(e.stack); -}); diff --git a/test/math/random-test.js b/test/math/random-test.js deleted file mode 100644 index 02738c660a49ff..00000000000000 --- a/test/math/random-test.js +++ /dev/null @@ -1,37 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.random"); - -suite.addBatch({ - "random": { - topic: load("math/random").expression("d3.random"), - "normal": { - "topic": function(random) { - return random.normal(); - }, - "returns a number": function(r) { - assert.typeOf(r(), "number"); - } - }, - "logNormal": { - "topic": function(random) { - return random.logNormal(); - }, - "returns a number": function(r) { - assert.typeOf(r(), "number"); - } - }, - "irwinHall": { - "topic": function(random) { - return random.irwinHall(10); - }, - "returns a number": function(r) { - assert.typeOf(r(), "number"); - } - } - } -}); - -suite.export(module); diff --git a/test/math/transform-null-matrix-test.html b/test/math/transform-null-matrix-test.html deleted file mode 100644 index 7a5eec3c258a23..00000000000000 --- a/test/math/transform-null-matrix-test.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - diff --git a/test/math/transform-null-test.html b/test/math/transform-null-test.html deleted file mode 100644 index 621168039791d7..00000000000000 --- a/test/math/transform-null-test.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - diff --git a/test/math/transform-rotate-origin-test.html b/test/math/transform-rotate-origin-test.html deleted file mode 100644 index 5a006f5cc85163..00000000000000 --- a/test/math/transform-rotate-origin-test.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/test/math/transform-rotate-test.html b/test/math/transform-rotate-test.html deleted file mode 100644 index 49fb5715a7824f..00000000000000 --- a/test/math/transform-rotate-test.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - -
startendactual intermediate valuesexp.act.
- - diff --git a/test/math/transform-test.html b/test/math/transform-test.html deleted file mode 100644 index 7e313d7876af67..00000000000000 --- a/test/math/transform-test.html +++ /dev/null @@ -1,88 +0,0 @@ - - -Transform Test - - - - diff --git a/test/scale/category-test.js b/test/scale/category-test.js deleted file mode 100644 index 76e8238e94a900..00000000000000 --- a/test/scale/category-test.js +++ /dev/null @@ -1,76 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.category"); - -suite.addBatch({ - "category": { - topic: load("scale/category").expression("d3.scale"), - "category10": category("category10", 10), - "category20": category("category20", 20), - "category20b": category("category20b", 20), - "category20c": category("category20c", 20) - } -}); - -function category(category, n) { - return { - "is an ordinal scale": function(scale) { - var x = scale[category](), colors = x.range(); - assert.lengthOf(x.domain(), 0); - assert.lengthOf(x.range(), n); - assert.equal(x(1), colors[0]); - assert.equal(x(2), colors[1]); - assert.equal(x(1), colors[0]); - var y = x.copy(); - assert.deepEqual(y.domain(), x.domain()); - assert.deepEqual(y.range(), x.range()); - x.domain(_.range(n)); - for (var i = 0; i < n; ++i) assert.equal(x(i + n), x(i)); - assert.equal(y(1), colors[0]); - assert.equal(y(2), colors[1]); - }, - "each instance is isolated": function(scale) { - var a = scale[category](), b = scale[category](), colors = a.range(); - assert.equal(a(1), colors[0]); - assert.equal(b(2), colors[0]); - assert.equal(b(1), colors[1]); - assert.equal(a(1), colors[0]); - }, - "contains the expected number of values in the range": function(scale) { - var x = scale[category](); - assert.lengthOf(x.range(), n); - }, - "each range value is distinct": function(scale) { - var map = {}, count = 0, x = scale[category](); - x.range().forEach(function(v) { - if (!(v in map)) { - map[v] = ++count; - } - }); - assert.equal(count, x.range().length); - }, - "each range value is a hexadecimal color": function(scale) { - var x = scale[category](); - x.range().forEach(function(v) { - assert.match(v, /#[0-9a-f]{6}/); - v = _.rgb(v); - assert.isFalse(isNaN(v.r)); - assert.isFalse(isNaN(v.g)); - assert.isFalse(isNaN(v.b)); - }); - }, - "no range values are very dark or very light": function(scale) { - var x = scale[category](); - x.range().forEach(function(v) { - var c = _.hsl(v); - assert.isTrue(c.l >= .34, "expected " + v + " to be lighter (l = " + c.l + ")"); - assert.isTrue(c.l <= .89, "expected " + v + " to be darker (l = " + c.l + ")"); - }); - } - }; -} - -suite.export(module); diff --git a/test/scale/identity-test.js b/test/scale/identity-test.js deleted file mode 100644 index 6ad815edb99e3c..00000000000000 --- a/test/scale/identity-test.js +++ /dev/null @@ -1,163 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.identity"); - -suite.addBatch({ - "identity": { - topic: load("scale/identity").expression("d3.scale.identity"), - - "domain and range": { - "are identical": function(identity) { - var x = identity(); - assert.strictEqual(x.domain, x.range); - assert.strictEqual(x.domain(), x.range()); - var x = identity().domain([-10, 0, 100]); - assert.deepEqual(x.range(), [-10, 0, 100]); - var x = identity().range([-10, 0, 100]); - assert.deepEqual(x.domain(), [-10, 0, 100]); - }, - "default to [0, 1]": function(identity) { - var x = identity(); - assert.deepEqual(x.domain(), [0, 1]); - assert.deepEqual(x.range(), [0, 1]); - assert.strictEqual(x(.5), .5); - }, - "coerce values to numbers": function(identity) { - var x = identity().domain([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.typeOf(x.domain()[0], "number"); - assert.typeOf(x.domain()[1], "number"); - assert.strictEqual(x.domain()[0], +new Date(1990, 0, 1)); - assert.strictEqual(x.domain()[1], +new Date(1991, 0, 1)); - assert.typeOf(x(new Date(1989, 09, 20)), "number"); - assert.strictEqual(x(new Date(1989, 09, 20)), +new Date(1989, 09, 20)); - var x = identity().domain(["0", "1"]); - assert.typeOf(x.domain()[0], "number"); - assert.typeOf(x.domain()[1], "number"); - assert.strictEqual(x(.5), .5); - var x = identity().domain([new Number(0), new Number(1)]); - assert.typeOf(x.domain()[0], "number"); - assert.typeOf(x.domain()[1], "number"); - assert.strictEqual(x(.5), .5); - - var x = identity().range([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.typeOf(x.range()[0], "number"); - assert.typeOf(x.range()[1], "number"); - assert.strictEqual(x.range()[0], +new Date(1990, 0, 1)); - assert.strictEqual(x.range()[1], +new Date(1991, 0, 1)); - assert.typeOf(x(new Date(1989, 09, 20)), "number"); - assert.strictEqual(x(new Date(1989, 09, 20)), +new Date(1989, 09, 20)); - var x = identity().range(["0", "1"]); - assert.typeOf(x.range()[0], "number"); - assert.typeOf(x.range()[1], "number"); - assert.strictEqual(x(.5), .5); - var x = identity().range([new Number(0), new Number(1)]); - assert.typeOf(x.range()[0], "number"); - assert.typeOf(x.range()[1], "number"); - assert.strictEqual(x(.5), .5); - }, - "can specify a polyidentity domain and range": function(identity) { - var x = identity().domain([-10, 0, 100]); - assert.deepEqual(x.domain(), [-10, 0, 100]); - assert.strictEqual(x(-5), -5); - assert.strictEqual(x(50), 50); - assert.strictEqual(x(75), 75); - - var x = identity().range([-10, 0, 100]); - assert.deepEqual(x.range(), [-10, 0, 100]); - assert.strictEqual(x(-5), -5); - assert.strictEqual(x(50), 50); - assert.strictEqual(x(75), 75); - }, - "do not affect the identity function": function(identity) { - var x = identity().domain([Infinity, NaN]); - assert.strictEqual(x(42), 42); - assert.strictEqual(x.invert(-42), -42); - } - }, - - "is the identity function": function(identity) { - var x = identity().domain([1, 2]); - assert.strictEqual(x(.5), .5); - assert.strictEqual(x(1), 1); - assert.strictEqual(x(1.5), 1.5); - assert.strictEqual(x(2), 2); - assert.strictEqual(x(2.5), 2.5); - }, - "coerces input to a number": function(identity) { - var x = identity().domain([1, 2]); - assert.strictEqual(x("2"), 2); - }, - - "invert": { - "is the identity function": function(identity) { - var x = identity().domain([1, 2]); - assert.strictEqual(x.invert(.5), .5); - assert.strictEqual(x.invert(1), 1); - assert.strictEqual(x.invert(1.5), 1.5); - assert.strictEqual(x.invert(2), 2); - assert.strictEqual(x.invert(2.5), 2.5); - }, - "coerces range value to numbers": function(identity) { - var x = identity().range(["0", "2"]); - assert.strictEqual(x.invert("1"), 1); - var x = identity().range([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.strictEqual(x.invert(new Date(1990, 6, 2, 13)), +new Date(1990, 6, 2, 13)); - var x = identity().range(["#000", "#fff"]); - assert.isNaN(x.invert("#999")); - }, - "coerces input to a number": function(identity) { - var x = identity().domain([1, 2]); - assert.strictEqual(x.invert("2"), 2); - } - }, - - "ticks": { - "generates ticks of varying degree": function(identity) { - var x = identity(); - assert.deepEqual(x.ticks(1).map(x.tickFormat(1)), [0, 1]); - assert.deepEqual(x.ticks(2).map(x.tickFormat(2)), [0, .5, 1]); - assert.deepEqual(x.ticks(5).map(x.tickFormat(5)), [0, .2, .4, .6, .8, 1]); - assert.deepEqual(x.ticks(10).map(x.tickFormat(10)), [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]); - var x = identity().domain([1, 0]); - assert.deepEqual(x.ticks(1).map(x.tickFormat(1)), [0, 1]); - assert.deepEqual(x.ticks(2).map(x.tickFormat(2)), [0, .5, 1]); - assert.deepEqual(x.ticks(5).map(x.tickFormat(5)), [0, .2, .4, .6, .8, 1]); - assert.deepEqual(x.ticks(10).map(x.tickFormat(10)), [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]); - }, - "formats ticks with the appropriate precision": function(identity) { - var x = identity().domain([.123456789, 1.23456789]); - assert.strictEqual(x.tickFormat(1)(x.ticks(1)[0]), "1"); - assert.strictEqual(x.tickFormat(2)(x.ticks(2)[0]), "0.5"); - assert.strictEqual(x.tickFormat(4)(x.ticks(4)[0]), "0.2"); - assert.strictEqual(x.tickFormat(8)(x.ticks(8)[0]), "0.2"); - assert.strictEqual(x.tickFormat(16)(x.ticks(16)[0]), "0.2"); - assert.strictEqual(x.tickFormat(32)(x.ticks(32)[0]), "0.15"); - assert.strictEqual(x.tickFormat(64)(x.ticks(64)[0]), "0.14"); - assert.strictEqual(x.tickFormat(128)(x.ticks(128)[0]), "0.13"); - assert.strictEqual(x.tickFormat(256)(x.ticks(256)[0]), "0.125"); - } - }, - - "copy": { - "changes to the domain or range are isolated": function(identity) { - var x = identity(), y = x.copy(); - x.domain([1, 2]); - assert.deepEqual(y.domain(), [0, 1]); - y.domain([2, 3]); - assert.deepEqual(x.domain(), [1, 2]); - assert.deepEqual(y.domain(), [2, 3]); - - var x = identity(), y = x.copy(); - x.range([1, 2]); - assert.deepEqual(y.range(), [0, 1]); - y.range([2, 3]); - assert.deepEqual(x.range(), [1, 2]); - assert.deepEqual(y.range(), [2, 3]); - } - } - } -}); - -suite.export(module); diff --git a/test/scale/linear-test.js b/test/scale/linear-test.js deleted file mode 100644 index 3af10ca7521fc9..00000000000000 --- a/test/scale/linear-test.js +++ /dev/null @@ -1,298 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.linear"); - -suite.addBatch({ - "linear": { - topic: load("scale/linear", "interpolate/hsl"), // beware instanceof d3_Color - - "domain": { - "defaults to [0, 1]": function(d3) { - var x = d3.scale.linear(); - assert.deepEqual(x.domain(), [0, 1]); - assert.inDelta(x(.5), .5, 1e-6); - }, - "coerces domain values to numbers": function(d3) { - var x = d3.scale.linear().domain([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(new Date(1989, 09, 20)), -.2, 1e-2); - assert.inDelta(x(new Date(1990, 00, 01)), 0, 1e-2); - assert.inDelta(x(new Date(1990, 02, 15)), .2, 1e-2); - assert.inDelta(x(new Date(1990, 04, 27)), .4, 1e-2); - assert.inDelta(x(new Date(1991, 00, 01)), 1, 1e-2); - assert.inDelta(x(new Date(1991, 02, 15)), 1.2, 1e-2); - var x = d3.scale.linear().domain(["0", "1"]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(.5), .5, 1e-6); - var x = d3.scale.linear().domain([new Number(0), new Number(1)]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(.5), .5, 1e-6); - }, - "can specify a polylinear domain and range": function(d3) { - var x = d3.scale.linear().domain([-10, 0, 100]).range(["red", "white", "green"]); - assert.equal(x(-5), "#ff8080"); - assert.equal(x(50), "#80c080"); - assert.equal(x(75), "#40a040"); - }, - "the smaller of the domain or range is observed": function(d3) { - var x = d3.scale.linear().domain([-10, 0]).range(["red", "white", "green"]).clamp(true); - assert.equal(x(-5), "#ff8080"); - assert.equal(x(50), "#ffffff"); - var x = d3.scale.linear().domain([-10, 0, 100]).range(["red", "white"]).clamp(true); - assert.equal(x(-5), "#ff8080"); - assert.equal(x(50), "#ffffff"); - }, - "an empty domain maps to the range start": function(d3) { - var x = d3.scale.linear().domain([0, 0]).range(["red", "green"]); - assert.equal(x(0), "#ff0000"); - assert.equal(x(-1), "#ff0000"); - assert.equal(x(1), "#ff0000"); - } - }, - - "range": { - "defaults to [0, 1]": function(d3) { - var x = d3.scale.linear(); - assert.deepEqual(x.range(), [0, 1]); - assert.inDelta(x.invert(.5), .5, 1e-6); - }, - "does not coerce range to numbers": function(d3) { - var x = d3.scale.linear().range(["0", "2"]); - assert.equal(typeof x.range()[0], "string"); - assert.equal(typeof x.range()[1], "string"); - }, - "can specify range values as colors": function(d3) { - var x = d3.scale.linear().range(["red", "blue"]); - assert.equal(x(.5), "#800080"); - var x = d3.scale.linear().range(["#ff0000", "#0000ff"]); - assert.equal(x(.5), "#800080"); - var x = d3.scale.linear().range(["#f00", "#00f"]); - assert.equal(x(.5), "#800080"); - var x = d3.scale.linear().range([d3.rgb(255,0,0), d3.hsl(240,1,.5)]); - assert.equal(x(.5), "#800080"); - var x = d3.scale.linear().range(["hsl(0,100%,50%)", "hsl(240,100%,50%)"]); - assert.equal(x(.5), "#800080"); - }, - "can specify range values as arrays or objects": function(d3) { - var x = d3.scale.linear().range([{color: "red"}, {color: "blue"}]); - assert.deepEqual(x(.5), {color: "#800080"}); - var x = d3.scale.linear().range([["red"], ["blue"]]); - assert.deepEqual(x(.5), ["#800080"]); - } - }, - - "interpolate": { - "defaults to d3.interpolate": function(d3) { - var x = d3.scale.linear().range(["red", "blue"]); - assert.equal(x.interpolate(), d3.interpolate); - assert.equal(x(.5), "#800080"); - }, - "can specify a custom interpolator": function(d3) { - var x = d3.scale.linear().range(["red", "blue"]).interpolate(d3.interpolateHsl); - assert.equal(x(.5), "#ff00ff"); - } - }, - - "clamp": { - "defaults to false": function(d3) { - var x = d3.scale.linear(); - assert.isFalse(x.clamp()); - assert.inDelta(x(-.5), -.5, 1e-6); - assert.inDelta(x(1.5), 1.5, 1e-6); - }, - "can clamp to the domain": function(d3) { - var x = d3.scale.linear().clamp(true); - assert.inDelta(x(-.5), 0, 1e-6); - assert.inDelta(x(.5), .5, 1e-6); - assert.inDelta(x(1.5), 1, 1e-6); - var x = d3.scale.linear().domain([1, 0]).clamp(true); - assert.inDelta(x(-.5), 1, 1e-6); - assert.inDelta(x(.5), .5, 1e-6); - assert.inDelta(x(1.5), 0, 1e-6); - }, - "can clamp to the range": function(d3) { - var x = d3.scale.linear().clamp(true); - assert.inDelta(x.invert(-.5), 0, 1e-6); - assert.inDelta(x.invert(.5), .5, 1e-6); - assert.inDelta(x.invert(1.5), 1, 1e-6); - var x = d3.scale.linear().range([1, 0]).clamp(true); - assert.inDelta(x.invert(-.5), 1, 1e-6); - assert.inDelta(x.invert(.5), .5, 1e-6); - assert.inDelta(x.invert(1.5), 0, 1e-6); - } - }, - - "maps a number to a number": function(d3) { - var x = d3.scale.linear().domain([1, 2]); - assert.inDelta(x(.5), -.5, 1e-6); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), .5, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - assert.inDelta(x(2.5), 1.5, 1e-6); - }, - - "invert": { - "maps a number to a number": function(d3) { - var x = d3.scale.linear().range([1, 2]); - assert.inDelta(x.invert(.5), -.5, 1e-6); - assert.inDelta(x.invert(1), 0, 1e-6); - assert.inDelta(x.invert(1.5), .5, 1e-6); - assert.inDelta(x.invert(2), 1, 1e-6); - assert.inDelta(x.invert(2.5), 1.5, 1e-6); - }, - "coerces range value to numbers": function(d3) { - var x = d3.scale.linear().range(["0", "2"]); - assert.inDelta(x.invert("1"), .5, 1e-6); - var x = d3.scale.linear().range([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.inDelta(x.invert(new Date(1990, 6, 2, 13)), .5, 1e-6); - var x = d3.scale.linear().range(["#000", "#fff"]); - assert.isNaN(x.invert("#999")); - }, - "can invert a polylinear descending domain": function(d3) { - var x = d3.scale.linear().domain([4, 2, 1]).range([1, 2, 4]); - assert.inDelta(x(1.5), 3, 1e-6); - assert.inDelta(x(3), 1.5, 1e-6); - assert.inDelta(x.invert(1.5), 3, 1e-6); - assert.inDelta(x.invert(3), 1.5, 1e-6); - }, - "can invert a polylinear descending range": function(d3) { - var x = d3.scale.linear().domain([1, 2, 4]).range([4, 2, 1]); - assert.inDelta(x(1.5), 3, 1e-6); - assert.inDelta(x(3), 1.5, 1e-6); - assert.inDelta(x.invert(1.5), 3, 1e-6); - assert.inDelta(x.invert(3), 1.5, 1e-6); - } - }, - - "ticks": { - "generates ticks of varying degree": function(d3) { - var x = d3.scale.linear(); - assert.deepEqual(x.ticks(1).map(x.tickFormat(1)), [0, 1]); - assert.deepEqual(x.ticks(2).map(x.tickFormat(2)), [0, .5, 1]); - assert.deepEqual(x.ticks(5).map(x.tickFormat(5)), [0, .2, .4, .6, .8, 1]); - assert.deepEqual(x.ticks(10).map(x.tickFormat(10)), [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]); - var x = d3.scale.linear().domain([1, 0]); - assert.deepEqual(x.ticks(1).map(x.tickFormat(1)), [0, 1]); - assert.deepEqual(x.ticks(2).map(x.tickFormat(2)), [0, .5, 1]); - assert.deepEqual(x.ticks(5).map(x.tickFormat(5)), [0, .2, .4, .6, .8, 1]); - assert.deepEqual(x.ticks(10).map(x.tickFormat(10)), [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]); - }, - "formats ticks with the appropriate precision": function(d3) { - var x = d3.scale.linear().domain([.123456789, 1.23456789]); - assert.strictEqual(x.tickFormat(1)(x.ticks(1)[0]), "1"); - assert.strictEqual(x.tickFormat(2)(x.ticks(2)[0]), "0.5"); - assert.strictEqual(x.tickFormat(4)(x.ticks(4)[0]), "0.2"); - assert.strictEqual(x.tickFormat(8)(x.ticks(8)[0]), "0.2"); - assert.strictEqual(x.tickFormat(16)(x.ticks(16)[0]), "0.2"); - assert.strictEqual(x.tickFormat(32)(x.ticks(32)[0]), "0.15"); - assert.strictEqual(x.tickFormat(64)(x.ticks(64)[0]), "0.14"); - assert.strictEqual(x.tickFormat(128)(x.ticks(128)[0]), "0.13"); - assert.strictEqual(x.tickFormat(256)(x.ticks(256)[0]), "0.125"); - } - }, - - "tickFormat": { - "applies automatic precision when not explicitly specified": function(d3) { - var x = d3.scale.linear(); - assert.strictEqual(x.tickFormat(10, "f")(Math.PI), "3.1") - assert.strictEqual(x.tickFormat(100, "f")(Math.PI), "3.14"); - assert.strictEqual(x.tickFormat(100, "$f")(Math.PI), "$3.14"); - assert.strictEqual(x.domain([0, 100]).tickFormat(100, "%")(Math.PI), "314%"); - }, - "if count is not specified, defaults to 10": function(d3) { - var x = d3.scale.linear(); - assert.strictEqual(x.tickFormat()(Math.PI), "3.1"); - assert.strictEqual(x.tickFormat(1)(Math.PI), "3"); - assert.strictEqual(x.tickFormat(10)(Math.PI), "3.1"); - assert.strictEqual(x.tickFormat(100)(Math.PI), "3.14"); - } - }, - - "nice": { - "nices the domain, extending it to round numbers": function(d3) { - var x = d3.scale.linear().domain([1.1, 10.9]).nice(); - assert.deepEqual(x.domain(), [1, 11]); - var x = d3.scale.linear().domain([10.9, 1.1]).nice(); - assert.deepEqual(x.domain(), [11, 1]); - var x = d3.scale.linear().domain([.7, 11.001]).nice(); - assert.deepEqual(x.domain(), [0, 12]); - var x = d3.scale.linear().domain([123.1, 6.7]).nice(); - assert.deepEqual(x.domain(), [130, 0]); - var x = d3.scale.linear().domain([0, .49]).nice(); - assert.deepEqual(x.domain(), [0, .5]); - }, - "has no effect on degenerate domains": function(d3) { - var x = d3.scale.linear().domain([0, 0]).nice(); - assert.deepEqual(x.domain(), [0, 0]); - var x = d3.scale.linear().domain([.5, .5]).nice(); - assert.deepEqual(x.domain(), [.5, .5]); - }, - "nicing a polylinear domain only affects the extent": function(d3) { - var x = d3.scale.linear().domain([1.1, 1, 2, 3, 10.9]).nice(); - assert.deepEqual(x.domain(), [1, 1, 2, 3, 11]); - var x = d3.scale.linear().domain([123.1, 1, 2, 3, -.9]).nice(); - assert.deepEqual(x.domain(), [130, 1, 2, 3, -10]); - }, - "accepts a tick count to control nicing step": function(d3) { - var x = d3.scale.linear().domain([12, 87]).nice(5); - assert.deepEqual(x.domain(), [0, 100]); - var x = d3.scale.linear().domain([12, 87]).nice(10); - assert.deepEqual(x.domain(), [10, 90]); - var x = d3.scale.linear().domain([12, 87]).nice(100); - assert.deepEqual(x.domain(), [12, 87]); - } - }, - - "copy": { - "changes to the domain are isolated": function(d3) { - var x = d3.scale.linear(), y = x.copy(); - x.domain([1, 2]); - assert.deepEqual(y.domain(), [0, 1]); - assert.equal(x(1), 0); - assert.equal(y(1), 1); - y.domain([2, 3]); - assert.equal(x(2), 1); - assert.equal(y(2), 0); - assert.deepEqual(x.domain(), [1, 2]); - assert.deepEqual(y.domain(), [2, 3]); - }, - "changes to the range are isolated": function(d3) { - var x = d3.scale.linear(), y = x.copy(); - x.range([1, 2]); - assert.equal(x.invert(1), 0); - assert.equal(y.invert(1), 1); - assert.deepEqual(y.range(), [0, 1]); - y.range([2, 3]); - assert.equal(x.invert(2), 1); - assert.equal(y.invert(2), 0); - assert.deepEqual(x.range(), [1, 2]); - assert.deepEqual(y.range(), [2, 3]); - }, - "changes to the interpolator are isolated": function(d3) { - var x = d3.scale.linear().range(["red", "blue"]), y = x.copy(); - x.interpolate(d3.interpolateHsl); - assert.equal(x(0.5), "#ff00ff"); - assert.equal(y(0.5), "#800080"); - assert.equal(y.interpolate(), d3.interpolate); - }, - "changes to clamping are isolated": function(d3) { - var x = d3.scale.linear().clamp(true), y = x.copy(); - x.clamp(false); - assert.equal(x(2), 2); - assert.equal(y(2), 1); - assert.isTrue(y.clamp()); - y.clamp(false); - assert.equal(x(2), 2); - assert.equal(y(2), 2); - assert.isFalse(x.clamp()); - } - } - } -}); - -suite.export(module); diff --git a/test/scale/log-test.js b/test/scale/log-test.js deleted file mode 100644 index 5e372ae670099d..00000000000000 --- a/test/scale/log-test.js +++ /dev/null @@ -1,387 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.log"); - -suite.addBatch({ - "log": { - topic: load("scale/log", "interpolate/hsl"), // beware instanceof d3_Color - - "domain": { - "defaults to [1, 10], exactly": function(d3) { - var x = d3.scale.log(); - assert.deepEqual(x.domain(), [1, 10]); - assert.inDelta(x(5), 0.69897, 1e-6); - }, - "coerces domain values to numbers": function(d3) { - var x = d3.scale.log().domain([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(new Date(1989, 09, 20)), -.2, 1e-2); - assert.inDelta(x(new Date(1990, 00, 01)), 0, 1e-2); - assert.inDelta(x(new Date(1990, 02, 15)), .2, 1e-2); - assert.inDelta(x(new Date(1990, 04, 27)), .4, 1e-2); - assert.inDelta(x(new Date(1991, 00, 01)), 1, 1e-2); - assert.inDelta(x(new Date(1991, 02, 15)), 1.2, 1e-2); - var x = d3.scale.log().domain(["1", "10"]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(5), 0.69897, 1e-6); - var x = d3.scale.log().domain([new Number(1), new Number(10)]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(5), 0.69897, 1e-6); - }, - "can specify negative domain values": function(d3) { - var x = d3.scale.log().domain([-100, -1]); - assert.deepEqual(x.ticks().map(x.tickFormat()), [ - "-1e+2", - "-9e+1", "-8e+1", "-7e+1", "-6e+1", "-5e+1", "-4e+1", "-3e+1", "-2e+1", "-1e+1", - "-9e+0", "-8e+0", "-7e+0", "-6e+0", "-5e+0", "-4e+0", "-3e+0", "-2e+0", "-1e+0" - ]); - assert.inDelta(x(-50), 0.150515, 1e-6); - }, - "can specify a polylog domain and range": function(d3) { - var x = d3.scale.log().domain([.1, 1, 100]).range(["red", "white", "green"]); - assert.equal(x(.5), "#ffb2b2"); - assert.equal(x(50), "#269326"); - assert.equal(x(75), "#108810"); - }, - "preserves specified domain exactly, with no floating point error": function(d3) { - var x = d3.scale.log().domain([.1, 1000]); - assert.deepEqual(x.domain(), [.1, 1000]); - } - }, - - "range": { - "defaults to [0, 1]": function(d3) { - var x = d3.scale.log(); - assert.deepEqual(x.range(), [0, 1]); - assert.inDelta(x.invert(.5), 3.162278, 1e-6); - }, - "does not coerce range to numbers": function(d3) { - var x = d3.scale.log().range(["0", "2"]); - assert.equal(typeof x.range()[0], "string"); - assert.equal(typeof x.range()[1], "string"); - }, - "can specify range values as colors": function(d3) { - var x = d3.scale.log().range(["red", "blue"]); - assert.equal(x(5), "#4d00b2"); - var x = d3.scale.log().range(["#ff0000", "#0000ff"]); - assert.equal(x(5), "#4d00b2"); - var x = d3.scale.log().range(["#f00", "#00f"]); - assert.equal(x(5), "#4d00b2"); - var x = d3.scale.log().range([d3.rgb(255,0,0), d3.hsl(240,1,.5)]); - assert.equal(x(5), "#4d00b2"); - var x = d3.scale.log().range(["hsl(0,100%,50%)", "hsl(240,100%,50%)"]); - assert.equal(x(5), "#4d00b2"); - }, - "can specify range values as arrays or objects": function(d3) { - var x = d3.scale.log().range([{color: "red"}, {color: "blue"}]); - assert.deepEqual(x(5), {color: "#4d00b2"}); - var x = d3.scale.log().range([["red"], ["blue"]]); - assert.deepEqual(x(5), ["#4d00b2"]); - } - }, - - "interpolate": { - "defaults to d3.interpolate": function(d3) { - var x = d3.scale.log().range(["red", "blue"]); - assert.equal(x.interpolate(), d3.interpolate); - assert.equal(x(5), "#4d00b2"); - }, - "can specify a custom interpolator": function(d3) { - var x = d3.scale.log().range(["red", "blue"]).interpolate(d3.interpolateHsl); - assert.equal(x(5), "#9a00ff"); - } - }, - - "clamp": { - "defaults to false": function(d3) { - var x = d3.scale.log(); - assert.isFalse(x.clamp()); - assert.inDelta(x(.5), -0.3010299, 1e-6); - assert.inDelta(x(15), 1.1760913, 1e-6); - }, - "can clamp to the domain": function(d3) { - var x = d3.scale.log().clamp(true); - assert.inDelta(x(-1), 0, 1e-6); - assert.inDelta(x(5), 0.69897, 1e-6); - assert.inDelta(x(15), 1, 1e-6); - var x = d3.scale.log().domain([10, 1]).clamp(true); - assert.inDelta(x(-1), 1, 1e-6); - assert.inDelta(x(5), 0.30103, 1e-6); - assert.inDelta(x(15), 0, 1e-6); - }, - "can clamp to the range": function(d3) { - var x = d3.scale.log().clamp(true); - assert.inDelta(x.invert(-.1), 1, 1e-6); - assert.inDelta(x.invert(0.69897), 5, 1e-6); - assert.inDelta(x.invert(1.5), 10, 1e-6); - var x = d3.scale.log().domain([10, 1]).clamp(true); - assert.inDelta(x.invert(-.1), 10, 1e-6); - assert.inDelta(x.invert(0.30103), 5, 1e-6); - assert.inDelta(x.invert(1.5), 1, 1e-6); - } - }, - - "maps a number to a number": function(d3) { - var x = d3.scale.log().domain([1, 2]); - assert.inDelta(x(.5), -1, 1e-6); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), 0.5849625, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - assert.inDelta(x(2.5), 1.3219281, 1e-6); - }, - - "invert": { - "maps a number to a number": function(d3) { - var x = d3.scale.log().domain([1, 2]); - assert.inDelta(x.invert(-1), .5, 1e-6); - assert.inDelta(x.invert(0), 1, 1e-6); - assert.inDelta(x.invert(0.5849625), 1.5, 1e-6); - assert.inDelta(x.invert(1), 2, 1e-6); - assert.inDelta(x.invert(1.3219281), 2.5, 1e-6); - }, - "coerces range value to number on invert": function(d3) { - var x = d3.scale.log().range(["0", "2"]); - assert.inDelta(x.invert("1"), 3.1622777, 1e-6); - var x = d3.scale.log().range([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.inDelta(x.invert(new Date(1990, 6, 2, 13)), 3.1622777, 1e-6); - var x = d3.scale.log().range(["#000", "#fff"]); - assert.isNaN(x.invert("#999")); - } - }, - - "ticks": { - "can generate ticks": function(d3) { - var x = d3.scale.log(); - assert.deepEqual(x.ticks().map(x.tickFormat()), [ - "1e+0", "2e+0", "3e+0", "4e+0", "5e+0", "6e+0", "7e+0", "8e+0", "9e+0", - "1e+1" - ]); - var x = d3.scale.log().domain([100, 1]); - assert.deepEqual(x.ticks().map(x.tickFormat()), [ - "1e+0", "2e+0", "3e+0", "4e+0", "5e+0", "6e+0", "7e+0", "8e+0", "9e+0", - "1e+1", "2e+1", "3e+1", "4e+1", "5e+1", "6e+1", "7e+1", "8e+1", "9e+1", - "1e+2" - ]); - var x = d3.scale.log().domain([0.49999, 0.006029505943610648]); - assert.deepEqual(x.ticks().map(x.tickFormat()), [ - "7e-3", "8e-3", "9e-3", "1e-2", "2e-2", "3e-2", "4e-2", "5e-2", - "6e-2", "7e-2", "8e-2", "9e-2", "1e-1", "2e-1", "3e-1", "4e-1" - ]); - var x = d3.scale.log().domain([.95, 1.05e8]); - assert.deepEqual(x.ticks().map(x.tickFormat(8)).filter(String), [ - '1e+0', '1e+1', '1e+2', '1e+3', '1e+4', '1e+5', '1e+6', '1e+7', '1e+8' - ]); - }, - "can generate fewer ticks, if desired": function(d3) { - var x = d3.scale.log(); - assert.deepEqual(x.ticks().map(x.tickFormat(5)), [ - "1e+0", "2e+0", "3e+0", "4e+0", "5e+0", "", "", "", "", - "1e+1" - ]); - var x = d3.scale.log().domain([100, 1]); - assert.deepEqual(x.ticks().map(x.tickFormat(10)), [ - "1e+0", "2e+0", "3e+0", "4e+0", "5e+0", "", "", "", "", - "1e+1", "2e+1", "3e+1", "4e+1", "5e+1", "", "", "", "", - "1e+2" - ]); - }, - "generates powers-of-ten ticks, even for huge domains": function(d3) { - var x = d3.scale.log().domain([1e10, 1]); - assert.deepEqual(x.ticks().map(x.tickFormat(10)), [ - "1e+0", "", "", "", "", "", "", "", "", - "1e+1", "", "", "", "", "", "", "", "", - "1e+2", "", "", "", "", "", "", "", "", - "1e+3", "", "", "", "", "", "", "", "", - "1e+4", "", "", "", "", "", "", "", "", - "1e+5", "", "", "", "", "", "", "", "", - "1e+6", "", "", "", "", "", "", "", "", - "1e+7", "", "", "", "", "", "", "", "", - "1e+8", "", "", "", "", "", "", "", "", - "1e+9", "", "", "", "", "", "", "", "", - "1e+10" - ]); - }, - "generates ticks that cover the domain": function(d3) { - var x = d3.scale.log().domain([.01, 10000]); - assert.deepEqual(x.ticks(20).map(x.tickFormat(20)), [ - "1e-2", "2e-2", "3e-2", "", "", "", "", "", "", - "1e-1", "2e-1", "3e-1", "", "", "", "", "", "", - "1e+0", "2e+0", "3e+0", "", "", "", "", "", "", - "1e+1", "2e+1", "3e+1", "", "", "", "", "", "", - "1e+2", "2e+2", "3e+2", "", "", "", "", "", "", - "1e+3", "2e+3", "3e+3", "", "", "", "", "", "", - "1e+4" - ]); - }, - "generates ticks that cover the niced domain": function(d3) { - var x = d3.scale.log().domain([.0124123, 1230.4]).nice(); - assert.deepEqual(x.ticks(20).map(x.tickFormat(20)), [ - "1e-2", "2e-2", "3e-2", "", "", "", "", "", "", - "1e-1", "2e-1", "3e-1", "", "", "", "", "", "", - "1e+0", "2e+0", "3e+0", "", "", "", "", "", "", - "1e+1", "2e+1", "3e+1", "", "", "", "", "", "", - "1e+2", "2e+2", "3e+2", "", "", "", "", "", "", - "1e+3", "2e+3", "3e+3", "", "", "", "", "", "", - "1e+4" - ]); - }, - "can override the tick format": function(d3) { - var x = d3.scale.log().domain([1000.1, 1]); - assert.deepEqual(x.ticks().map(x.tickFormat(10, d3.format("+,d"))), [ - "+1", "+2", "+3", "", "", "", "", "", "", - "+10", "+20", "+30", "", "", "", "", "", "", - "+100", "+200", "+300", "", "", "", "", "", "", - "+1,000" - ]); - }, - "can override the tick format as string": function(d3) { - var x = d3.scale.log().domain([1000.1, 1]); - assert.deepEqual(x.ticks().map(x.tickFormat(10, ".1s")), [ - "1", "2", "3", "", "", "", "", "", "", - "10", "20", "30", "", "", "", "", "", "", - "100", "200", "300", "", "", "", "", "", "", - "1k" - ]); - }, - "generates empty ticks when the domain is degenerate": function(d3) { - var x = d3.scale.log(); - assert.deepEqual(x.domain([0, 1]).ticks(), []); - assert.deepEqual(x.domain([1, 0]).ticks(), []); - assert.deepEqual(x.domain([0, -1]).ticks(), []); - assert.deepEqual(x.domain([-1, 0]).ticks(), []); - assert.deepEqual(x.domain([-1, 1]).ticks(), []); - assert.deepEqual(x.domain([0, 0]).ticks(), []); - } - }, - - "base two": { - topic: function(d3) { - return d3.scale.log().domain([1, 32]).base(2); - }, - "with a suitable tick format": { - topic: function(x, d3) { - return x.ticks().map(x.tickFormat(10, d3.format("+,d"))); - }, - "generates ticks at powers of two": function(ticks) { - assert.deepEqual(ticks, [ - "+1", "+2", "+4", "+8", "+16", "+32" - ]); - } - } - }, - - "base e": { - topic: function(d3) { - return d3.scale.log().domain([1, 32]).base(Math.E); - }, - "with a suitable tick format": { - topic: function(x, d3) { - return x.ticks().map(x.tickFormat(10, d3.format("+.6r"))); - }, - "generates ticks at powers of e": function(ticks) { - assert.deepEqual(ticks, [ - "+1.00000", "+2.71828", "+7.38906", "+20.0855" - ]); - } - } - }, - - "nice": { - "can nice the domain, extending it to powers of ten": function(d3) { - var x = d3.scale.log().domain([1.1, 10.9]).nice(); - assert.inDelta(x.domain(), [1, 100], 1e-6); - var x = d3.scale.log().domain([10.9, 1.1]).nice(); - assert.inDelta(x.domain(), [100, 1], 1e-6); - var x = d3.scale.log().domain([.7, 11.001]).nice(); - assert.inDelta(x.domain(), [.1, 100], 1e-6); - var x = d3.scale.log().domain([123.1, 6.7]).nice(); - assert.inDelta(x.domain(), [1000, 1], 1e-6); - var x = d3.scale.log().domain([.01, .49]).nice(); - assert.inDelta(x.domain(), [.01, 1], 1e-6); - }, - "works on degenerate domains": function(d3) { - var x = d3.scale.log().domain([0, 0]).nice(); - assert.inDelta(x.domain(), [0, 0], 1e-6); - var x = d3.scale.log().domain([.5, .5]).nice(); - assert.inDelta(x.domain(), [.1, 1], 1e-6); - }, - "nicing a polylog domain only affects the extent": function(d3) { - var x = d3.scale.log().domain([1.1, 1.5, 10.9]).nice(); - assert.inDelta(x.domain(), [1, 1.5, 100], 1e-6); - var x = d3.scale.log().domain([-123.1, -1.5, -.5]).nice(); - assert.inDelta(x.domain(), [-1000, -1.5, -.1], 1e-6); - }, - "the niced domain is subsequently used by the scale": function(d3) { - var x = d3.scale.log().domain([1.5, 50]).nice(); - assert.inDelta(x.domain(), [1, 100], 1e-6); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(100), 1, 1e-6); - } - }, - - "copy": { - "changes to the domain are isolated": function(d3) { - var x = d3.scale.log(), y = x.copy(); - x.domain([10, 100]); - assert.inDelta(y.domain(), [1, 10], 1e-6); - assert.inDelta(x(10), 0, 1e-6); - assert.inDelta(y(1), 0, 1e-6); - y.domain([100, 1000]); - assert.inDelta(x(100), 1, 1e-6); - assert.inDelta(y(100), 0, 1e-6); - assert.inDelta(x.domain(), [10, 100], 1e-6); - assert.inDelta(y.domain(), [100, 1000], 1e-6); - }, - "changes to the range are isolated": function(d3) { - var x = d3.scale.log(), y = x.copy(); - x.range([1, 2]); - assert.inDelta(x.invert(1), 1, 1e-6); - assert.inDelta(y.invert(1), 10, 1e-6); - assert.deepEqual(y.range(), [0, 1]); - y.range([2, 3]); - assert.inDelta(x.invert(2), 10, 1e-6); - assert.inDelta(y.invert(2), 1, 1e-6); - assert.deepEqual(x.range(), [1, 2]); - assert.deepEqual(y.range(), [2, 3]); - }, - "changes to the interpolator are isolated": function(d3) { - var x = d3.scale.log().range(["red", "blue"]), y = x.copy(); - x.interpolate(d3.interpolateHsl); - assert.equal(x(5), "#9a00ff"); - assert.equal(y(5), "#4d00b2"); - assert.equal(y.interpolate(), d3.interpolate); - }, - "changes to clamping are isolated": function(d3) { - var x = d3.scale.log().clamp(true), y = x.copy(); - x.clamp(false); - assert.inDelta(x(.5), -0.30103, 1e-6); - assert.inDelta(y(.5), 0, 1e-6); - assert.isTrue(y.clamp()); - y.clamp(false); - assert.inDelta(x(20), 1.30103, 1e-6); - assert.inDelta(y(20), 1.30103, 1e-6); - assert.isFalse(x.clamp()); - }, - "changes to nicing are isolated": function(d3) { - var x = d3.scale.log().domain([1.5, 50]), y = x.copy().nice(); - assert.inDelta(x.domain(), [1.5, 50], 1e-6); - assert.inDelta(x(1.5), 0, 1e-6); - assert.inDelta(x(50), 1, 1e-6); - assert.inDelta(x.invert(0), 1.5, 1e-6); - assert.inDelta(x.invert(1), 50, 1e-6); - assert.inDelta(y.domain(), [1, 100], 1e-6); - assert.inDelta(y(1), 0, 1e-6); - assert.inDelta(y(100), 1, 1e-6); - assert.inDelta(y.invert(0), 1, 1e-6); - assert.inDelta(y.invert(1), 100, 1e-6); - } - } - } -}); - -suite.export(module); diff --git a/test/scale/ordinal-test.js b/test/scale/ordinal-test.js deleted file mode 100644 index f60c4554e93eab..00000000000000 --- a/test/scale/ordinal-test.js +++ /dev/null @@ -1,305 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.ordinal"); - -suite.addBatch({ - "ordinal": { - topic: load("scale/ordinal").expression("d3.scale.ordinal"), - - "domain": { - "defaults to the empty array": function(ordinal) { - assert.isEmpty(ordinal().domain()); - }, - "setting the domain forgets previous values": function(ordinal) { - var x = ordinal().range(["foo", "bar"]); - assert.equal(x(1), "foo"); - assert.equal(x(0), "bar"); - assert.deepEqual(x.domain(), [1, 0]); - x.domain(["0", "1"]); - assert.equal(x(0), "foo"); // it changed! - assert.equal(x(1), "bar"); - assert.deepEqual(x.domain(), ["0", "1"]); - }, - "uniqueness is based on string coercion": function(ordinal) { - var x = ordinal().domain(["foo"]).range([42, 43, 44]); - assert.equal(x(new String("foo")), 42); - assert.equal(x({toString: function() { return "foo"; }}), 42); - assert.equal(x({toString: function() { return "bar"; }}), 43); - }, - "does not coerce domain values to strings": function(ordinal) { - var x = ordinal().domain([0, 1]); - assert.deepEqual(x.domain(), [0, 1]); - assert.typeOf(x.domain()[0], "number"); - assert.typeOf(x.domain()[1], "number"); - }, - "does not barf on object built-ins": function(ordinal) { - var x = ordinal().domain(["__proto__", "hasOwnProperty"]).range([42, 43]); - assert.equal(x("__proto__"), 42); - assert.equal(x("hasOwnProperty"), 43); - assert.deepEqual(x.domain(), ["__proto__", "hasOwnProperty"]); - } - }, - - "range": { - "defaults to the empty array": function(ordinal) { - var x = ordinal(); - assert.isEmpty(x.range()); - assert.isUndefined(x(0)); - }, - "new input values are added to the domain": function(ordinal) { - var x = ordinal().range(["foo", "bar"]); - assert.equal(x(0), "foo"); - assert.deepEqual(x.domain(), ["0"]); - assert.equal(x(1), "bar"); - assert.deepEqual(x.domain(), ["0", "1"]); - assert.equal(x(0), "foo"); - assert.deepEqual(x.domain(), ["0", "1"]); - }, - "orders domain values by the order in which they are seen": function(ordinal) { - var x = ordinal(); - x("foo"); - x("bar"); - x("baz"); - assert.deepEqual(x.domain(), ["foo", "bar", "baz"]); - x.domain(["baz", "bar"]); - x("foo"); - assert.deepEqual(x.domain(), ["baz", "bar", "foo"]); - x.domain(["baz", "foo"]); - assert.deepEqual(x.domain(), ["baz", "foo"]); - x.domain([]); - x("foo"); - x("bar"); - assert.deepEqual(x.domain(), ["foo", "bar"]); - }, - "setting the range remembers previous values": function(ordinal) { - var x = ordinal(); - assert.isUndefined(x(0)); - assert.isUndefined(x(1)); - x.range(["foo", "bar"]); - assert.equal(x(0), "foo"); - assert.equal(x(1), "bar"); - }, - "recycles values when exhausted": function(ordinal) { - var x = ordinal().range(["a", "b", "c"]); - assert.equal(x(0), "a"); - assert.equal(x(1), "b"); - assert.equal(x(2), "c"); - assert.equal(x(3), "a"); - assert.equal(x(4), "b"); - assert.equal(x(5), "c"); - assert.equal(x(2), "c"); - assert.equal(x(1), "b"); - assert.equal(x(0), "a"); - } - }, - - "maps distinct values to discrete values": function(ordinal) { - var x = ordinal().range(["a", "b", "c"]); - assert.equal(x(0), "a"); - assert.equal(x("0"), "a"); - assert.equal(x([0]), "a"); - assert.equal(x(1), "b"); - assert.equal(x(2.0), "c"); - assert.equal(x(new Number(2)), "c"); - }, - - "rangePoints": { - "computes discrete points in a continuous range": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangePoints([0, 120]); - assert.deepEqual(x.range(), [0, 60, 120]); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([0, 120], 1); - assert.deepEqual(x.range(), [20, 60, 100]); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([0, 120], 2); - assert.deepEqual(x.range(), [30, 60, 90]); - }, - "correctly handles singleton domains": function(ordinal) { - var x = ordinal().domain(["a"]).rangePoints([0, 120]); - assert.deepEqual(x.range(), [60]); - }, - "can be set to a descending range": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangePoints([120, 0]); - assert.deepEqual(x.range(), [120, 60,0]); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([120, 0], 1); - assert.deepEqual(x.range(), [100, 60, 20]); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([120, 0], 2); - assert.deepEqual(x.range(), [90, 60, 30]); - }, - "has a rangeBand of zero": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangePoints([0, 120]); - assert.equal(x.rangeBand(), 0); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([0, 120], 1); - assert.equal(x.rangeBand(), 0); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([0, 120], 2); - assert.equal(x.rangeBand(), 0); - var x = ordinal().domain(["a"]).rangePoints([0, 120]); - assert.equal(x.rangeBand(), 0); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([120, 0]); - assert.equal(x.rangeBand(), 0); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([120, 0], 1); - assert.equal(x.rangeBand(), 0); - var x = ordinal().domain(["a", "b", "c"]).rangePoints([120, 0], 2); - assert.equal(x.rangeBand(), 0); - }, - "returns undefined for values outside the domain": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangePoints([0, 1]); - assert.isUndefined(x("d")); - assert.isUndefined(x("e")); - assert.isUndefined(x("f")); - }, - "does not implicitly add values to the domain": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangePoints([0, 1]); - x("d"), x("e"); - assert.deepEqual(x.domain(), ["a", "b", "c"]); - } - }, - - "rangeBands": { - "computes discrete bands in a continuous range": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeBands([0, 120]); - assert.deepEqual(x.range(), [0, 40, 80]); - assert.equal(x.rangeBand(), 40); - var x = ordinal().domain(["a", "b", "c"]).rangeBands([0, 120], .2); - assert.deepEqual(x.range(), [7.5, 45, 82.5]); - assert.equal(x.rangeBand(), 30); - }, - "setting domain recomputes range bands": function(ordinal) { - var x = ordinal().rangeRoundBands([0, 100]).domain(["a", "b", "c"]); - assert.deepEqual(x.range(), [1, 34, 67]); - assert.equal(x.rangeBand(), 33); - x.domain(["a", "b", "c", "d"]); - assert.deepEqual(x.range(), [0, 25, 50, 75]); - assert.equal(x.rangeBand(), 25); - }, - "can be set to a descending range": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeBands([120, 0]); - assert.deepEqual(x.range(), [80, 40, 0]); - assert.equal(x.rangeBand(), 40); - var x = ordinal().domain(["a", "b", "c"]).rangeBands([120, 0], .2); - assert.deepEqual(x.range(), [82.5, 45, 7.5]); - assert.equal(x.rangeBand(), 30); - }, - "can specify a different outer padding": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeBands([120, 0], .2, .1); - assert.deepEqual(x.range(), [84, 44, 4]); - assert.equal(x.rangeBand(), 32); - var x = ordinal().domain(["a", "b", "c"]).rangeBands([120, 0], .2, 1); - assert.deepEqual(x.range(), [75, 50, 25]); - assert.equal(x.rangeBand(), 20); - }, - "returns undefined for values outside the domain": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeBands([0, 1]); - assert.isUndefined(x("d")); - assert.isUndefined(x("e")); - assert.isUndefined(x("f")); - }, - "does not implicitly add values to the domain": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeBands([0, 1]); - x("d"), x("e"); - assert.deepEqual(x.domain(), ["a", "b", "c"]); - } - }, - - "rangeRoundBands": { - "computes discrete rounded bands in a continuous range": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([0, 100]); - assert.deepEqual(x.range(), [1, 34, 67]); - assert.equal(x.rangeBand(), 33); - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([0, 100], .2); - assert.deepEqual(x.range(), [7, 38, 69]); - assert.equal(x.rangeBand(), 25); - }, - "can be set to a descending range": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([100, 0]); - assert.deepEqual(x.range(), [67, 34, 1]); - assert.equal(x.rangeBand(), 33); - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([100, 0], .2); - assert.deepEqual(x.range(), [69, 38, 7]); - assert.equal(x.rangeBand(), 25); - }, - "can specify a different outer padding": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([120, 0], .2, .1); - assert.deepEqual(x.range(), [84, 44, 4]); - assert.equal(x.rangeBand(), 32); - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([120, 0], .2, 1); - assert.deepEqual(x.range(), [75, 50, 25]); - assert.equal(x.rangeBand(), 20); - }, - "returns undefined for values outside the domain": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([0, 1]); - assert.isUndefined(x("d")); - assert.isUndefined(x("e")); - assert.isUndefined(x("f")); - }, - "does not implicitly add values to the domain": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([0, 1]); - x("d"), x("e"); - assert.deepEqual(x.domain(), ["a", "b", "c"]); - } - }, - - "rangeExtent": { - "returns the continuous range": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangePoints([20, 120]); - assert.deepEqual(x.rangeExtent(), [20, 120]); - var x = ordinal().domain(["a", "b", "c"]).rangeBands([10, 110]); - assert.deepEqual(x.rangeExtent(), [10, 110]); - var x = ordinal().domain(["a", "b", "c"]).rangeRoundBands([0, 100]); - assert.deepEqual(x.rangeExtent(), [0, 100]); - var x = ordinal().domain(["a", "b", "c"]).range([0, 20, 100]); - assert.deepEqual(x.rangeExtent(), [0, 100]); - }, - "can handle descending ranges": function(ordinal) { - var x = ordinal().domain(["a", "b", "c"]).rangeBands([100, 0]); - assert.deepEqual(x.rangeExtent(), [0, 100]); - } - }, - - "copy": { - "changes to the domain are isolated": function(ordinal) { - var x = ordinal().range(["foo", "bar"]), y = x.copy(); - x.domain([1, 2]); - assert.deepEqual(y.domain(), []); - assert.equal(x(1), "foo"); - assert.equal(y(1), "foo"); - y.domain([2, 3]); - assert.equal(x(2), "bar"); - assert.equal(y(2), "foo"); - assert.deepEqual(x.domain(), ["1", "2"]); - assert.deepEqual(y.domain(), ["2", "3"]); - }, - "changes to the range are isolated": function(ordinal) { - var x = ordinal().range(["foo", "bar"]), y = x.copy(); - x.range(["bar", "foo"]); - assert.equal(x(1), "bar"); - assert.equal(y(1), "foo"); - assert.deepEqual(y.range(), ["foo", "bar"]); - y.range(["foo", "baz"]); - assert.equal(x(2), "foo"); - assert.equal(y(2), "baz"); - assert.deepEqual(x.range(), ["bar", "foo"]); - assert.deepEqual(y.range(), ["foo", "baz"]); - }, - "changes to the range type are isolated": function(ordinal) { - var x = ordinal().domain([0, 1]).rangeBands([0, 1], .2), y = x.copy(); - x.rangePoints([1, 2]); - assert.inDelta(x(0), 1, 1e-6); - assert.inDelta(x(1), 2, 1e-6); - assert.inDelta(x.rangeBand(), 0, 1e-6); - assert.inDelta(y(0), 1/11, 1e-6); - assert.inDelta(y(1), 6/11, 1e-6); - assert.inDelta(y.rangeBand(), 4/11, 1e-6); - y.rangeBands([0, 1]); - assert.inDelta(x(0), 1, 1e-6); - assert.inDelta(x(1), 2, 1e-6); - assert.inDelta(x.rangeBand(), 0, 1e-6); - assert.inDelta(y(0), 0, 1e-6); - assert.inDelta(y(1), 1/2, 1e-6); - assert.inDelta(y.rangeBand(), 1/2, 1e-6); - } - } - } -}); - -suite.export(module); diff --git a/test/scale/pow-test.js b/test/scale/pow-test.js deleted file mode 100644 index 74c252a394cddc..00000000000000 --- a/test/scale/pow-test.js +++ /dev/null @@ -1,277 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.pow"); - -suite.addBatch({ - "pow": { - topic: load("scale/pow", "interpolate/hsl"), // beware instance of d3_Colorr - - "domain": { - "defaults to [0, 1]": function(d3) { - var x = d3.scale.pow(); - assert.deepEqual(x.domain(), [0, 1]); - assert.inDelta(x(.5), .5, 1e-6); - }, - "coerces domain to numbers": function(d3) { - var x = d3.scale.pow().domain([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(new Date(1989, 09, 20)), -.2, 1e-2); - assert.inDelta(x(new Date(1990, 00, 01)), 0, 1e-2); - assert.inDelta(x(new Date(1990, 02, 15)), .2, 1e-2); - assert.inDelta(x(new Date(1990, 04, 27)), .4, 1e-2); - assert.inDelta(x(new Date(1991, 00, 01)), 1, 1e-2); - assert.inDelta(x(new Date(1991, 02, 15)), 1.2, 1e-2); - var x = d3.scale.pow().domain(["0", "1"]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(.5), .5, 1e-6); - var x = d3.scale.pow().domain([new Number(0), new Number(1)]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(.5), .5, 1e-6); - }, - "can specify a polypower domain and range": function(d3) { - var x = d3.scale.pow().domain([-10, 0, 100]).range(["red", "white", "green"]); - assert.equal(x(-5), "#ff8080"); - assert.equal(x(50), "#80c080"); - assert.equal(x(75), "#40a040"); - } - }, - - "range": { - "defaults to [0, 1]": function(d3) { - var x = d3.scale.pow(); - assert.deepEqual(x.range(), [0, 1]); - assert.inDelta(x.invert(.5), .5, 1e-6); - }, - "does not coerce range values to numbers": function(d3) { - var x = d3.scale.pow().range(["0", "2"]); - assert.equal(typeof x.range()[0], "string"); - assert.equal(typeof x.range()[1], "string"); - }, - "coerces range values to number on invert": function(d3) { - var x = d3.scale.pow().range(["0", "2"]); - assert.inDelta(x.invert("1"), .5, 1e-6); - var x = d3.scale.pow().range([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.inDelta(x.invert(new Date(1990, 6, 2, 13)), .5, 1e-6); - var x = d3.scale.pow().range(["#000", "#fff"]); - assert.isNaN(x.invert("#999")); - }, - "can specify range values as colors": function(d3) { - var x = d3.scale.pow().range(["red", "blue"]); - assert.equal(x(.5), "#800080"); - var x = d3.scale.pow().range(["#ff0000", "#0000ff"]); - assert.equal(x(.5), "#800080"); - var x = d3.scale.pow().range(["#f00", "#00f"]); - assert.equal(x(.5), "#800080"); - var x = d3.scale.pow().range([d3.rgb(255,0,0), d3.hsl(240,1,.5)]); - assert.equal(x(.5), "#800080"); - var x = d3.scale.pow().range(["hsl(0,100%,50%)", "hsl(240,100%,50%)"]); - assert.equal(x(.5), "#800080"); - }, - "can specify range values as arrays or objects": function(d3) { - var x = d3.scale.pow().range([{color: "red"}, {color: "blue"}]); - assert.deepEqual(x(.5), {color: "#800080"}); - var x = d3.scale.pow().range([["red"], ["blue"]]); - assert.deepEqual(x(.5), ["#800080"]); - } - }, - - "exponent": { - "defaults to one": function(d3) { - var x = d3.scale.pow(); - assert.equal(x.exponent(), 1); - }, - "observes the specified exponent": function(d3) { - var x = d3.scale.pow().exponent(.5).domain([1, 2]); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), 0.5425821, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - assert.equal(x.exponent(), .5); - var x = d3.scale.pow().exponent(2).domain([1, 2]); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), .41666667, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - assert.equal(x.exponent(), 2); - var x = d3.scale.pow().exponent(-1).domain([1, 2]); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), .6666667, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - assert.equal(x.exponent(), -1); - }, - "changing the exponent does not change the domain or range": function(d3) { - var x = d3.scale.pow().domain([1, 2]).range([3, 4]), f = d3.format(".6f"); - x.exponent(.5); - assert.deepEqual(x.domain().map(f), [1, 2]); - assert.deepEqual(x.range(), [3, 4]); - x.exponent(2); - assert.deepEqual(x.domain().map(f), [1, 2]); - assert.deepEqual(x.range(), [3, 4]); - x.exponent(-1); - assert.deepEqual(x.domain().map(f), [1, 2]); - assert.deepEqual(x.range(), [3, 4]); - } - }, - - "interpolate": { - "defaults to d3.interpolate": function(d3) { - var x = d3.scale.pow().range(["red", "blue"]); - assert.equal(x.interpolate(), d3.interpolate); - assert.equal(x(.5), "#800080"); - }, - "can specify a custom interpolator": function(d3) { - var x = d3.scale.pow().range(["red", "blue"]).interpolate(d3.interpolateHsl); - assert.equal(x(.5), "#ff00ff"); - } - }, - - "clamp": { - "does not clamp by default": function(d3) { - var x = d3.scale.pow(); - assert.isFalse(x.clamp()); - assert.inDelta(x(-.5), -.5, 1e-6); - assert.inDelta(x(1.5), 1.5, 1e-6); - }, - "can clamp to the domain": function(d3) { - var x = d3.scale.pow().clamp(true); - assert.inDelta(x(-.5), 0, 1e-6); - assert.inDelta(x(.5), .5, 1e-6); - assert.inDelta(x(1.5), 1, 1e-6); - var x = d3.scale.pow().domain([1, 0]).clamp(true); - assert.inDelta(x(-.5), 1, 1e-6); - assert.inDelta(x(.5), .5, 1e-6); - assert.inDelta(x(1.5), 0, 1e-6); - } - }, - - "maps a number to a number": function(d3) { - var x = d3.scale.pow().domain([1, 2]); - assert.inDelta(x(.5), -.5, 1e-6); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), .5, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - assert.inDelta(x(2.5), 1.5, 1e-6); - }, - - "ticks": { - "can generate ticks of varying degree": function(d3) { - var x = d3.scale.pow(); - assert.deepEqual(x.ticks(1).map(x.tickFormat(1)), [0, 1]); - assert.deepEqual(x.ticks(2).map(x.tickFormat(2)), [0, .5, 1]); - assert.deepEqual(x.ticks(5).map(x.tickFormat(5)), [0, .2, .4, .6, .8, 1]); - assert.deepEqual(x.ticks(10).map(x.tickFormat(10)), [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]); - var x = d3.scale.pow().domain([1, 0]); - assert.deepEqual(x.ticks(1).map(x.tickFormat(1)), [0, 1]); - assert.deepEqual(x.ticks(2).map(x.tickFormat(2)), [0, .5, 1]); - assert.deepEqual(x.ticks(5).map(x.tickFormat(5)), [0, .2, .4, .6, .8, 1]); - assert.deepEqual(x.ticks(10).map(x.tickFormat(10)), [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]); - } - }, - - "tickFormat": { - "if count is not specified, defaults to 10": function(d3) { - var x = d3.scale.pow(); - assert.strictEqual(x.tickFormat()(Math.PI), "3.1"); - assert.strictEqual(x.tickFormat(1)(Math.PI), "3"); - assert.strictEqual(x.tickFormat(10)(Math.PI), "3.1"); - assert.strictEqual(x.tickFormat(100)(Math.PI), "3.14"); - } - }, - - "nice": { - "can nice the domain, extending it to round numbers": function(d3) { - var x = d3.scale.pow().domain([1.1, 10.9]).nice(); - assert.deepEqual(x.domain(), [1, 11]); - var x = d3.scale.pow().domain([10.9, 1.1]).nice(); - assert.deepEqual(x.domain(), [11, 1]); - var x = d3.scale.pow().domain([.7, 11.001]).nice(); - assert.deepEqual(x.domain(), [0, 12]); - var x = d3.scale.pow().domain([123.1, 6.7]).nice(); - assert.deepEqual(x.domain(), [130, 0]); - var x = d3.scale.pow().domain([0, .49]).nice(); - assert.deepEqual(x.domain(), [0, .5]); - var x = d3.scale.pow().domain([0, 0]).nice(); - assert.deepEqual(x.domain(), [0, 0]); - var x = d3.scale.pow().domain([.5, .5]).nice(); - assert.deepEqual(x.domain(), [.5, .5]); - }, - "nicing a polypower domain only affects the extent": function(d3) { - var x = d3.scale.pow().domain([1.1, 1, 2, 3, 10.9]).nice(); - assert.deepEqual(x.domain(), [1, 1, 2, 3, 11]); - var x = d3.scale.pow().domain([123.1, 1, 2, 3, -.9]).nice(); - assert.deepEqual(x.domain(), [130, 1, 2, 3, -10]); - }, - "accepts a tick count to control nicing step": function(d3) { - var x = d3.scale.pow().domain([12, 87]).nice(5); - assert.deepEqual(x.domain(), [0, 100]); - var x = d3.scale.pow().domain([12, 87]).nice(10); - assert.deepEqual(x.domain(), [10, 90]); - var x = d3.scale.pow().domain([12, 87]).nice(100); - assert.deepEqual(x.domain(), [12, 87]); - } - }, - - "copy": { - "changes to the domain are isolated": function(d3) { - var x = d3.scale.pow(), y = x.copy(); - x.domain([1, 2]); - assert.deepEqual(y.domain(), [0, 1]); - assert.equal(x(1), 0); - assert.equal(y(1), 1); - y.domain([2, 3]); - assert.equal(x(2), 1); - assert.equal(y(2), 0); - assert.deepEqual(x.domain(), [1, 2]); - assert.deepEqual(y.domain(), [2, 3]); - }, - "changes to the range are isolated": function(d3) { - var x = d3.scale.pow(), y = x.copy(); - x.range([1, 2]); - assert.equal(x.invert(1), 0); - assert.equal(y.invert(1), 1); - assert.deepEqual(y.range(), [0, 1]); - y.range([2, 3]); - assert.equal(x.invert(2), 1); - assert.equal(y.invert(2), 0); - assert.deepEqual(x.range(), [1, 2]); - assert.deepEqual(y.range(), [2, 3]); - }, - "changes to the exponent are isolated": function(d3) { - var x = d3.scale.pow().exponent(2), y = x.copy(); - x.exponent(.5); - assert.inDelta(x(.5), Math.SQRT1_2, 1e-6); - assert.inDelta(y(.5), 0.25, 1e-6); - assert.equal(x.exponent(), .5); - assert.equal(y.exponent(), 2); - y.exponent(3); - assert.inDelta(x(.5), Math.SQRT1_2, 1e-6); - assert.inDelta(y(.5), 0.125, 1e-6); - assert.equal(x.exponent(), .5); - assert.equal(y.exponent(), 3); - }, - "changes to the interpolator are isolated": function(d3) { - var x = d3.scale.pow().range(["red", "blue"]), y = x.copy(); - x.interpolate(d3.interpolateHsl); - assert.equal(x(0.5), "#ff00ff"); - assert.equal(y(0.5), "#800080"); - assert.equal(y.interpolate(), d3.interpolate); - }, - "changes to clamping are isolated": function(d3) { - var x = d3.scale.pow().clamp(true), y = x.copy(); - x.clamp(false); - assert.equal(x(2), 2); - assert.equal(y(2), 1); - assert.isTrue(y.clamp()); - y.clamp(false); - assert.equal(x(2), 2); - assert.equal(y(2), 2); - assert.isFalse(x.clamp()); - } - } - } -}); - -suite.export(module); diff --git a/test/scale/quantile-test.js b/test/scale/quantile-test.js deleted file mode 100644 index 9a2ff7e0a81836..00000000000000 --- a/test/scale/quantile-test.js +++ /dev/null @@ -1,91 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.quantile"); - -suite.addBatch({ - "quantile": { - topic: load("scale/quantile").expression("d3.scale.quantile"), - "has the empty domain by default": function(quantile) { - assert.isEmpty(quantile().domain()); - }, - "has the empty range by default": function(quantile) { - assert.isEmpty(quantile().range()); - }, - "uses the R-7 algorithm to compute quantiles": function(quantile) { - var x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]).range([0, 1, 2, 3]); - assert.deepEqual([3, 6, 6.9, 7, 7.1].map(x), [0, 0, 0, 0, 0]); - assert.deepEqual([8, 8.9].map(x), [1, 1]); - assert.deepEqual([9, 9.1, 10, 13].map(x), [2, 2, 2, 2]); - assert.deepEqual([14.9, 15, 15.1, 16, 20].map(x), [3, 3, 3, 3, 3]); - var x = quantile().domain([3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20]).range([0, 1, 2, 3]); - assert.deepEqual([3, 6, 6.9, 7, 7.1].map(x), [0, 0, 0, 0, 0]); - assert.deepEqual([8, 8.9].map(x), [1, 1]); - assert.deepEqual([9, 9.1, 10, 13].map(x), [2, 2, 2, 2]); - assert.deepEqual([14.9, 15, 15.1, 16, 20].map(x), [3, 3, 3, 3, 3]); - }, - "domain values are sorted in ascending order": function(quantile) { - var x = quantile().domain([6, 3, 7, 8, 8, 13, 20, 15, 16, 10]); - assert.deepEqual(x.domain(), [3, 6, 7, 8, 8, 10, 13, 15, 16, 20]); - }, - "non-numeric domain values are ignored": function(quantile) { - var x = quantile().domain([6, 3, NaN, undefined, 7, 8, 8, 13, 20, 15, 16, 10, NaN]); - assert.deepEqual(x.domain(), [3, 6, 7, 8, 8, 10, 13, 15, 16, 20]); - }, - "quantiles returns the inner thresholds": function(quantile) { - var x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]).range([0, 1, 2, 3]); - assert.deepEqual(x.quantiles(), [7.25, 9, 14.5]); - var x = quantile().domain([3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20]).range([0, 1, 2, 3]); - assert.deepEqual(x.quantiles(), [7.5, 9, 14]); - }, - "range cardinality determines the number of quantiles": function(quantile) { - var x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]); - assert.deepEqual(x.range([0, 1, 2, 3]).quantiles(), [7.25, 9, 14.5]); - assert.deepEqual(x.range([0, 1]).quantiles(), [9]); - assert.deepEqual(x.range([,,,,,]).quantiles(), [6.8, 8, 11.2, 15.2]); - assert.deepEqual(x.range([,,,,,,]).quantiles(), [6.5, 8, 9, 13, 15.5]); - }, - "range values are arbitrary": function(quantile) { - var a = new Object(), b = new Object(), c = new Object(); - var x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]).range([a, b, c, a]); - assert.deepEqual([3, 6, 6.9, 7, 7.1].map(x), [a, a, a, a, a]); - assert.deepEqual([8, 8.9].map(x), [b, b]); - assert.deepEqual([9, 9.1, 10, 13].map(x), [c, c, c, c]); - assert.deepEqual([14.9, 15, 15.1, 16, 20].map(x), [a, a, a, a, a]); - }, - "returns undefined if the input value is NaN": function(quantile) { - var x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]).range([0, 1, 2, 3]); - assert.isUndefined(x(NaN)); - }, - "invertExtent": { - "maps a value in the range to a domain extent": function(quantile) { - var x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]).range([0, 1, 2, 3]); - assert.deepEqual(x.invertExtent(0), [3, 7.25]); - assert.deepEqual(x.invertExtent(1), [7.25, 9]); - assert.deepEqual(x.invertExtent(2), [9, 14.5]); - assert.deepEqual(x.invertExtent(3), [14.5, 20]); - }, - "allows arbitrary range values": function(quantile) { - var a = {}, b = {}, x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]).range([a, b]); - assert.deepEqual(x.invertExtent(a), [3, 9]); - assert.deepEqual(x.invertExtent(b), [9, 20]); - }, - "returns [NaN, NaN] when the given value is not in the range": function(quantile) { - var x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]); - assert.ok(x.invertExtent(-1).every(isNaN)); - assert.ok(x.invertExtent(.5).every(isNaN)); - assert.ok(x.invertExtent(2).every(isNaN)); - assert.ok(x.invertExtent('a').every(isNaN)); - }, - "returns the first match if duplicate values exist in the range": function(quantile) { - var x = quantile().domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20]).range([0, 1, 2, 0]); - assert.deepEqual(x.invertExtent(0), [3, 7.25]); - assert.deepEqual(x.invertExtent(1), [7.25, 9]); - assert.deepEqual(x.invertExtent(2), [9, 14.5]); - } - } - } -}); - -suite.export(module); diff --git a/test/scale/quantize-test.js b/test/scale/quantize-test.js deleted file mode 100644 index a3f58c2993bf11..00000000000000 --- a/test/scale/quantize-test.js +++ /dev/null @@ -1,92 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.quantize"); - -suite.addBatch({ - "quantize": { - topic: load("scale/quantize").expression("d3.scale.quantize"), - "has the default domain [0, 1]": function(quantize) { - var x = quantize(); - assert.deepEqual(x.domain(), [0, 1]); - assert.equal(x(.25), 0); - }, - "has the default range [0, 1]": function(quantize) { - var x = quantize(); - assert.deepEqual(x.range(), [0, 1]); - assert.equal(x(.75), 1); - }, - "maps a number to a discrete value in the range": function(quantize) { - var x = quantize().range([0, 1, 2]); - assert.equal(x(0), 0); - assert.equal(x(.2), 0); - assert.equal(x(.4), 1); - assert.equal(x(.6), 1); - assert.equal(x(.8), 2); - assert.equal(x(1), 2); - }, - "coerces domain to numbers": function(quantize) { - var x = quantize().domain(["0", "100"]); - assert.strictEqual(x.domain()[0], 0); - assert.strictEqual(x.domain()[1], 100); - }, - "only considers the extent of the domain": function(quantize) { - var x = quantize().domain([-1, 0, 100]); - assert.deepEqual(x.domain(), [-1, 100]); - }, - "clamps input values to the domain": function(quantize) { - var a = {}, b = {}, c = {}, x = quantize().range([a, b, c]); - assert.equal(x(-.5), a); - assert.equal(x(1.5), c); - }, - "range cardinality determines the degree of quantization": function(quantize) { - var x = quantize(); - assert.inDelta(x.range(_.range(0, 1.001, .001))(1/3), .333, 1e-6); - assert.inDelta(x.range(_.range(0, 1.01, .01))(1/3), .33, 1e-6); - assert.inDelta(x.range(_.range(0, 1.1, .1))(1/3), .3, 1e-6); - assert.inDelta(x.range(_.range(0, 1.2, .2))(1/3), .4, 1e-6); - assert.inDelta(x.range(_.range(0, 1.25, .25))(1/3), .25, 1e-6); - assert.inDelta(x.range(_.range(0, 1.5, .5))(1/3), .5, 1e-6); - assert.inDelta(x.range(_.range(1))(1/3), 0, 1e-6); - }, - "range values are arbitrary": function(quantize) { - var a = {}, b = {}, c = {}, x = quantize().range([a, b, c]); - assert.equal(x(0), a); - assert.equal(x(.2), a); - assert.equal(x(.4), b); - assert.equal(x(.6), b); - assert.equal(x(.8), c); - assert.equal(x(1), c); - }, - "invertExtent": { - "maps a value in the range to a domain extent": function(quantize) { - var x = quantize().range([0, 1, 2, 3]); - assert.deepEqual(x.invertExtent(0), [0, .25]); - assert.deepEqual(x.invertExtent(1), [.25, .5]); - assert.deepEqual(x.invertExtent(2), [.5, .75]); - assert.deepEqual(x.invertExtent(3), [.75, 1]); - }, - "allows arbitrary range values": function(quantize) { - var a = {}, b = {}, x = quantize().range([a, b]); - assert.deepEqual(x.invertExtent(a), [0, .5]); - assert.deepEqual(x.invertExtent(b), [.5, 1]); - }, - "returns [NaN, NaN] when the given value is not in the range": function(quantize) { - var x = quantize(); - assert.ok(x.invertExtent(-1).every(isNaN)); - assert.ok(x.invertExtent(.5).every(isNaN)); - assert.ok(x.invertExtent(2).every(isNaN)); - assert.ok(x.invertExtent('a').every(isNaN)); - }, - "returns the first match if duplicate values exist in the range": function(quantize) { - var x = quantize().range([0, 1, 2, 0]); - assert.deepEqual(x.invertExtent(0), [0, .25]); - assert.deepEqual(x.invertExtent(1), [.25, .5]); - } - } - } -}); - -suite.export(module); diff --git a/test/scale/sqrt-test.js b/test/scale/sqrt-test.js deleted file mode 100644 index 96e23fcd1e0b32..00000000000000 --- a/test/scale/sqrt-test.js +++ /dev/null @@ -1,270 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.sqrt"); - -suite.addBatch({ - "sqrt": { - topic: load("scale/sqrt", "interpolate/hsl"), // beware instanceof d3_Color - - "domain": { - "defaults to [0, 1]": function(d3) { - var x = d3.scale.sqrt(); - assert.deepEqual(x.domain(), [0, 1]); - assert.inDelta(x(.5), 0.7071068, 1e-6); - }, - "coerces domain to numbers": function(d3) { - var x = d3.scale.sqrt().domain([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(new Date(1989, 09, 20)), -.2, 1e-2); - assert.inDelta(x(new Date(1990, 00, 01)), 0, 1e-2); - assert.inDelta(x(new Date(1990, 02, 15)), .2, 1e-2); - assert.inDelta(x(new Date(1990, 04, 27)), .4, 1e-2); - assert.inDelta(x(new Date(1991, 00, 01)), 1, 1e-2); - assert.inDelta(x(new Date(1991, 02, 15)), 1.2, 1e-2); - var x = d3.scale.sqrt().domain(["0", "1"]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(.5), 0.7071068, 1e-6); - var x = d3.scale.sqrt().domain([new Number(0), new Number(1)]); - assert.equal(typeof x.domain()[0], "number"); - assert.equal(typeof x.domain()[1], "number"); - assert.inDelta(x(.5), 0.7071068, 1e-6); - }, - "can specify a polypower domain and range": function(d3) { - var x = d3.scale.sqrt().domain([-10, 0, 100]).range(["red", "white", "green"]); - assert.equal(x(-5), "#ff4b4b"); - assert.equal(x(50), "#4ba54b"); - assert.equal(x(75), "#229122"); - }, - "preserves specified domain exactly, with no floating point error": function(d3) { - var x = d3.scale.sqrt().domain([0, 5]); - assert.deepEqual(x.domain(), [0, 5]); - } - }, - - "range": { - "defaults to [0, 1]": function(d3) { - var x = d3.scale.sqrt(); - assert.deepEqual(x.range(), [0, 1]); - assert.inDelta(x.invert(.5), .25, 1e-6); - }, - "does not coerce range to numbers": function(d3) { - var x = d3.scale.sqrt().range(["0", "2"]); - assert.equal(typeof x.range()[0], "string"); - assert.equal(typeof x.range()[1], "string"); - }, - "coerces range value to number on invert": function(d3) { - var x = d3.scale.sqrt().range(["0", "2"]); - assert.inDelta(x.invert("1"), .25, 1e-6); - var x = d3.scale.sqrt().range([new Date(1990, 0, 1), new Date(1991, 0, 1)]); - assert.inDelta(x.invert(new Date(1990, 6, 2, 13)), .25, 1e-6); - var x = d3.scale.sqrt().range(["#000", "#fff"]); - assert.isNaN(x.invert("#999")); - }, - "can specify range values as colors": function(d3) { - var x = d3.scale.sqrt().range(["red", "blue"]); - assert.equal(x(.25), "#800080"); - var x = d3.scale.sqrt().range(["#ff0000", "#0000ff"]); - assert.equal(x(.25), "#800080"); - var x = d3.scale.sqrt().range(["#f00", "#00f"]); - assert.equal(x(.25), "#800080"); - var x = d3.scale.sqrt().range([d3.rgb(255,0,0), d3.hsl(240,1,.5)]); - assert.equal(x(.25), "#800080"); - var x = d3.scale.sqrt().range(["hsl(0,100%,50%)", "hsl(240,100%,50%)"]); - assert.equal(x(.25), "#800080"); - }, - "can specify range values as arrays or objects": function(d3) { - var x = d3.scale.sqrt().range([{color: "red"}, {color: "blue"}]); - assert.deepEqual(x(.25), {color: "#800080"}); - var x = d3.scale.sqrt().range([["red"], ["blue"]]); - assert.deepEqual(x(.25), ["#800080"]); - } - }, - - "exponent": { - "defaults to .5": function(d3) { - var x = d3.scale.sqrt(); - assert.equal(x.exponent(), .5); - }, - "observes the specified exponent": function(d3) { - var x = d3.scale.sqrt().exponent(.5).domain([1, 2]); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), 0.5425821, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - var x = d3.scale.sqrt().exponent(2).domain([1, 2]); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), .41666667, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - var x = d3.scale.sqrt().exponent(-1).domain([1, 2]); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), .6666667, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - }, - "changing the exponent does not change the domain or range": function(d3) { - var x = d3.scale.sqrt().domain([1, 2]).range([3, 4]), f = d3.format(".6f"); - x.exponent(.5); - assert.deepEqual(x.domain().map(f), [1, 2]); - assert.deepEqual(x.range(), [3, 4]); - x.exponent(2); - assert.deepEqual(x.domain().map(f), [1, 2]); - assert.deepEqual(x.range(), [3, 4]); - x.exponent(-1); - assert.deepEqual(x.domain().map(f), [1, 2]); - assert.deepEqual(x.range(), [3, 4]); - } - }, - - "interpolate": { - "defaults to d3.interpolate": function(d3) { - var x = d3.scale.sqrt().range(["red", "blue"]); - assert.equal(x.interpolate(), d3.interpolate); - assert.equal(x(.5), "#4b00b4"); - }, - "can specify a custom interpolator": function(d3) { - var x = d3.scale.sqrt().range(["red", "blue"]).interpolate(d3.interpolateHsl); - assert.equal(x(.25), "#ff00ff"); - } - }, - - "clamp": { - "defaults to false": function(d3) { - var x = d3.scale.sqrt(); - assert.isFalse(x.clamp()); - assert.inDelta(x(-.5), -0.7071068, 1e-6); - assert.inDelta(x(1.5), 1.22474487, 1e-6); - }, - "can clamp to the domain": function(d3) { - var x = d3.scale.sqrt().clamp(true); - assert.inDelta(x(-.5), 0, 1e-6); - assert.inDelta(x(.25), .5, 1e-6); - assert.inDelta(x(1.5), 1, 1e-6); - var x = d3.scale.sqrt().domain([1, 0]).clamp(true); - assert.inDelta(x(-.5), 1, 1e-6); - assert.inDelta(x(.25), .5, 1e-6); - assert.inDelta(x(1.5), 0, 1e-6); - } - }, - - "maps a number to a number": function(d3) { - var x = d3.scale.sqrt().domain([1, 2]); - assert.inDelta(x(.5), -0.7071068, 1e-6); - assert.inDelta(x(1), 0, 1e-6); - assert.inDelta(x(1.5), 0.5425821, 1e-6); - assert.inDelta(x(2), 1, 1e-6); - assert.inDelta(x(2.5), 1.4029932, 1e-6); - }, - - "ticks": { - "can generate ticks of varying degree": function(d3) { - var x = d3.scale.sqrt(); - assert.deepEqual(x.ticks(1).map(x.tickFormat(1)), [0, 1]); - assert.deepEqual(x.ticks(2).map(x.tickFormat(2)), [0, .5, 1]); - assert.deepEqual(x.ticks(5).map(x.tickFormat(5)), [0, .2, .4, .6, .8, 1]); - assert.deepEqual(x.ticks(10).map(x.tickFormat(10)), [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]); - var x = d3.scale.sqrt().domain([1, 0]); - assert.deepEqual(x.ticks(1).map(x.tickFormat(1)), [0, 1]); - assert.deepEqual(x.ticks(2).map(x.tickFormat(2)), [0, .5, 1]); - assert.deepEqual(x.ticks(5).map(x.tickFormat(5)), [0, .2, .4, .6, .8, 1]); - assert.deepEqual(x.ticks(10).map(x.tickFormat(10)), [0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1]); - } - }, - - "tickFormat": { - "if count is not specified, defaults to 10": function(d3) { - var x = d3.scale.sqrt(); - assert.strictEqual(x.tickFormat()(Math.PI), "3.1"); - assert.strictEqual(x.tickFormat(1)(Math.PI), "3"); - assert.strictEqual(x.tickFormat(10)(Math.PI), "3.1"); - assert.strictEqual(x.tickFormat(100)(Math.PI), "3.14"); - } - }, - - "nice": { - "can nice the domain, extending it to round numbers": function(d3) { - var x = d3.scale.sqrt().domain([1.1, 10.9]).nice(), f = d3.format(".6f"); - assert.deepEqual(x.domain().map(f), [1, 11]); - var x = d3.scale.sqrt().domain([10.9, 1.1]).nice(); - assert.deepEqual(x.domain().map(f), [11, 1]); - var x = d3.scale.sqrt().domain([.7, 11.001]).nice(); - assert.deepEqual(x.domain().map(f), [0, 12]); - var x = d3.scale.sqrt().domain([123.1, 6.7]).nice(); - assert.deepEqual(x.domain().map(f), [130, 0]); - var x = d3.scale.sqrt().domain([0, .49]).nice(); - assert.deepEqual(x.domain().map(f), [0, .5]); - }, - "nicing a polypower domain only affects the extent": function(d3) { - var x = d3.scale.sqrt().domain([1.1, 1, 2, 3, 10.9]).nice(), f = d3.format(".6f"); - assert.deepEqual(x.domain().map(f), [1, 1, 2, 3, 11]); - var x = d3.scale.sqrt().domain([123.1, 1, 2, 3, -.9]).nice(); - assert.deepEqual(x.domain().map(f), [130, 1, 2, 3, "-10.000000"]); - }, - "preserves specified domain exactly, with no floating point error": function(d3) { - var x = d3.scale.sqrt().domain([0, 5]).nice(); - assert.deepEqual(x.domain(), [0, 5]); - } - }, - - "copy": { - "changes to the domain are isolated": function(d3) { - var x = d3.scale.sqrt(), y = x.copy(); - x.domain([1, 2]); - assert.deepEqual(y.domain(), [0, 1]); - assert.equal(x(1), 0); - assert.equal(y(1), 1); - y.domain([2, 3]); - assert.equal(x(2), 1); - assert.equal(y(2), 0); - assert.inDelta(x.domain(), [1, 2], 1e-6); - assert.inDelta(y.domain(), [2, 3], 1e-6); - }, - "changes to the range are isolated": function(d3) { - var x = d3.scale.sqrt(), y = x.copy(); - x.range([1, 2]); - assert.equal(x.invert(1), 0); - assert.equal(y.invert(1), 1); - assert.deepEqual(y.range(), [0, 1]); - y.range([2, 3]); - assert.equal(x.invert(2), 1); - assert.equal(y.invert(2), 0); - assert.deepEqual(x.range(), [1, 2]); - assert.deepEqual(y.range(), [2, 3]); - }, - "changes to the exponent are isolated": function(d3) { - var x = d3.scale.sqrt().exponent(2), y = x.copy(); - x.exponent(.5); - assert.inDelta(x(.5), Math.SQRT1_2, 1e-6); - assert.inDelta(y(.5), 0.25, 1e-6); - assert.equal(x.exponent(), .5); - assert.equal(y.exponent(), 2); - y.exponent(3); - assert.inDelta(x(.5), Math.SQRT1_2, 1e-6); - assert.inDelta(y(.5), 0.125, 1e-6); - assert.equal(x.exponent(), .5); - assert.equal(y.exponent(), 3); - }, - "changes to the interpolator are isolated": function(d3) { - var x = d3.scale.sqrt().range(["red", "blue"]), y = x.copy(); - x.interpolate(d3.interpolateHsl); - assert.equal(x(0.5), "#9500ff"); - assert.equal(y(0.5), "#4b00b4"); - assert.equal(y.interpolate(), d3.interpolate); - }, - "changes to clamping are isolated": function(d3) { - var x = d3.scale.sqrt().clamp(true), y = x.copy(); - x.clamp(false); - assert.equal(x(2), Math.SQRT2); - assert.equal(y(2), 1); - assert.isTrue(y.clamp()); - y.clamp(false); - assert.equal(x(2), Math.SQRT2); - assert.equal(y(2), Math.SQRT2); - assert.isFalse(x.clamp()); - } - } - } -}); - -suite.export(module); diff --git a/test/scale/threshold-test.js b/test/scale/threshold-test.js deleted file mode 100644 index 798b83aaa262a0..00000000000000 --- a/test/scale/threshold-test.js +++ /dev/null @@ -1,64 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.scale.threshold"); - -suite.addBatch({ - "threshold": { - topic: load("scale/threshold").expression("d3.scale.threshold"), - "has the default domain [.5]": function(threshold) { - var x = threshold(); - assert.deepEqual(x.domain(), [.5]); - assert.equal(x(.49), 0); - }, - "has the default range [0, 1]": function(threshold) { - var x = threshold(); - assert.deepEqual(x.range(), [0, 1]); - assert.equal(x(.50), 1); - }, - "maps a number to a discrete value in the range": function(threshold) { - var x = threshold().domain([1/3, 2/3]).range(["a", "b", "c"]); - assert.equal(x(0), "a"); - assert.equal(x(.2), "a"); - assert.equal(x(.4), "b"); - assert.equal(x(.6), "b"); - assert.equal(x(.8), "c"); - assert.equal(x(1), "c"); - }, - "returns undefined if the specified value is not orderable": function(threshold) { - var x = threshold().domain([1/3, 2/3]).range(["a", "b", "c"]); - assert.isUndefined(x()); - assert.isUndefined(x(undefined)); - assert.isUndefined(x(NaN)); - assert.equal(x(null), "a"); // null < 1/3 - }, - "domain values are arbitrary": function(threshold) { - var x = threshold().domain(["10", "2"]).range([0, 1, 2]); - assert.strictEqual(x.domain()[0], "10"); - assert.strictEqual(x.domain()[1], "2"); - assert.equal(x("0"), 0); - assert.equal(x("12"), 1); - assert.equal(x("3"), 2); - }, - "range values are arbitrary": function(threshold) { - var a = {}, b = {}, c = {}, x = threshold().domain([1/3, 2/3]).range([a, b, c]); - assert.equal(x(0), a); - assert.equal(x(.2), a); - assert.equal(x(.4), b); - assert.equal(x(.6), b); - assert.equal(x(.8), c); - assert.equal(x(1), c); - }, - "invertExtent": { - "returns the domain extent for the specified range value": function(threshold) { - var a = {}, b = {}, c = {}, x = threshold().domain([1/3, 2/3]).range([a, b, c]); - assert.deepEqual(x.invertExtent(a), [undefined, 1/3]); - assert.deepEqual(x.invertExtent(b), [1/3, 2/3]); - assert.deepEqual(x.invertExtent(c), [2/3, undefined]); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/append-test.js b/test/selection/append-test.js deleted file mode 100644 index b6c90db94d4c69..00000000000000 --- a/test/selection/append-test.js +++ /dev/null @@ -1,153 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.append"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/append").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "appends an HTML element": function(body) { - var div = body.append("div"); - assert.equal(div[0][0].tagName, "DIV"); - assert.isNull(div[0][0].namespaceURI); - assert.isTrue(div[0][0].parentNode === body.node()); - assert.isTrue(div[0][0] === body.node().lastChild); - }, - "appends an SVG element": function(body) { - var svg = body.append("svg:svg"); - assert.equal(svg[0][0].tagName, "SVG"); - assert.equal(svg[0][0].namespaceURI, "http://www.w3.org/2000/svg"); - assert.isTrue(svg[0][0].parentNode === body.node()); - assert.isTrue(svg[0][0] === body.node().lastChild); - }, - "appends an element specified as a function": function(body) { - var svg = body.select("svg").remove().node(); - assert.isFalse(svg === body.node().lastChild); - body.append(function() { return svg; }); - assert.isTrue(svg === body.node().lastChild); - }, - "propagates data to new element": function(body) { - var data = new Object(), div = body.data([data]).append("div"); - assert.strictEqual(div[0][0].__data__, data); - }, - "returns a new selection": function(body) { - assert.isFalse(body.append("div") === body); - }, - "inherits namespace from parent node": function(body) { - var g = body.append("svg:svg").append("g"); - assert.equal(g[0][0].namespaceURI, "http://www.w3.org/2000/svg"); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "appends an HTML element": function(div) { - var span = div.append("span"); - assert.equal(span[0].length, 2); - assert.equal(span[0][0].tagName, "SPAN"); - assert.equal(span[0][1].tagName, "SPAN"); - assert.isNull(span[0][0].namespaceURI); - assert.isNull(span[0][1].namespaceURI); - assert.isTrue(span[0][0].parentNode === div[0][0]); - assert.isTrue(span[0][1].parentNode === div[0][1]); - assert.isTrue(div[0][0].lastChild === span[0][0]); - assert.isTrue(div[0][1].lastChild === span[0][1]); - }, - "appends an SVG element": function(div) { - var svg = div.append("svg:svg"); - assert.equal(svg[0].length, 2); - assert.equal(svg[0][0].tagName, "SVG"); - assert.equal(svg[0][1].tagName, "SVG"); - assert.equal(svg[0][0].namespaceURI, "http://www.w3.org/2000/svg"); - assert.equal(svg[0][1].namespaceURI, "http://www.w3.org/2000/svg"); - assert.isTrue(svg[0][0].parentNode === div[0][0]); - assert.isTrue(svg[0][1].parentNode === div[0][1]); - assert.isTrue(div[0][0].lastChild === svg[0][0]); - assert.isTrue(div[0][1].lastChild === svg[0][1]); - }, - "propagates data to new elements": function(div) { - var a = new Object(), b = new Object(), span = div.data([a, b]).append("span"); - assert.strictEqual(span[0][0].__data__, a); - assert.strictEqual(span[0][1].__data__, b); - }, - "returns a new selection": function(div) { - assert.isFalse(div.append("div") === div); - }, - "ignores null nodes": function(div) { - var node = div.html("")[0][1]; - div[0][1] = null; - var span = div.append("span"); - assert.equal(span[0].length, 2); - assert.equal(span[0][0].tagName, "SPAN"); - assert.isNull(span[0][1]); - assert.isTrue(span[0][0].parentNode === div[0][0]); - assert.isTrue(div[0][0].lastChild === span[0][0]); - assert.isNull(node.lastChild); - } - } - } -}); - -suite.addBatch({ - "enter-append": { - topic: load("selection/selection").document(), - "on a page with existing elements": { - topic: function(d3) { - var body = d3.select("body"); - body.selectAll("div").data(["apple", "orange"]).enter().append("div"); - return body; - }, - "appends to the end of the parent": function(body) { - var data = ["peach", "apple", "banana", "orange", "apricot"]; - body.selectAll("div").data(data, String).enter().append("div"); - assert.deepEqual(body.selectAll("div").data(), ["apple", "orange", "peach", "banana", "apricot"]); - } - } - } -}); - -suite.addBatch({ - "selectAll(div).data(…).enter()": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "appends to the parent node": function(body) { - var div = body.selectAll("div").data([0, 1]).enter().append("div"); - assert.equal(div.length, 1); - assert.equal(div[0].length, 2); - assert.domEqual(div[0][0].parentNode, body.node()); - assert.domEqual(div[0][1].parentNode, body.node()); - }, - "propagates data to new elements": function(body) { - var a = new Object(), b = new Object(), div = body.html("").selectAll("div").data([a, b]).enter().append("div"); - assert.strictEqual(div[0][0].__data__, a); - assert.strictEqual(div[0][1].__data__, b); - }, - "ignores null nodes": function(body) { - body.html("").append("div"); - var div = body.selectAll("div").data([0, 1, 2]).enter().append("div"); - assert.equal(div.length, 1); - assert.equal(div[0].length, 3); - assert.domNull(div[0][0]); - assert.domEqual(div[0][1].parentNode, body.node()); - assert.domEqual(div[0][2].parentNode, body.node()); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/attr-test.js b/test/selection/attr-test.js deleted file mode 100644 index c69110e9cdf7da..00000000000000 --- a/test/selection/attr-test.js +++ /dev/null @@ -1,182 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.attr"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/attr").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "sets an attribute as a string": function(body) { - body.attr("bgcolor", "red"); - assert.equal(body.node().getAttribute("bgcolor"), "red"); - }, - "sets an attribute as a number": function(body) { - body.attr("opacity", 1); - assert.equal(body.node().getAttribute("opacity"), "1"); - }, - "sets an attribute as a function": function(body) { - body.attr("bgcolor", function() { return "orange"; }); - assert.equal(body.node().getAttribute("bgcolor"), "orange"); - }, - "sets an attribute as a function of data": function(body) { - body.data(["cyan"]).attr("bgcolor", String); - assert.equal(body.node().getAttribute("bgcolor"), "cyan"); - }, - "sets an attribute as a function of index": function(body) { - body.attr("bgcolor", function(d, i) { return "orange-" + i; }); - assert.equal(body.node().getAttribute("bgcolor"), "orange-0"); - }, - "sets a namespaced attribute as a string": function(body) { - body.attr("xlink:href", "url"); - assert.equal(body.node().getAttributeNS("http://www.w3.org/1999/xlink", "href"), "url"); - }, - "sets a namespaced attribute as a function": function(body) { - body.data(["orange"]).attr("xlink:href", function(d, i) { return d + "-" + i; }); - assert.equal(body.node().getAttributeNS("http://www.w3.org/1999/xlink", "href"), "orange-0"); - }, - "sets attributes as a map of constants": function(body) { - body.attr({bgcolor: "white", "xlink:href": "url.png"}); - assert.equal(body.node().getAttribute("bgcolor"), "white"); - assert.equal(body.node().getAttributeNS("http://www.w3.org/1999/xlink", "href"), "url.png"); - }, - "sets attributes as a map of functions": function(body) { - body.data(["orange"]).attr({"xlink:href": function(d, i) { return d + "-" + i + ".png"; }}); - assert.equal(body.node().getAttributeNS("http://www.w3.org/1999/xlink", "href"), "orange-0.png"); - }, - "gets an attribute value": function(body) { - body.node().setAttribute("bgcolor", "yellow"); - assert.equal(body.attr("bgcolor"), "yellow"); - }, - "gets a namespaced attribute value": function(body) { - body.node().setAttributeNS("http://www.w3.org/1999/xlink", "foo", "bar"); - assert.equal(body.attr("xlink:foo"), "bar"); - }, - "removes an attribute as null": function(body) { - body.attr("bgcolor", "red").attr("bgcolor", null); - assert.isNull(body.attr("bgcolor")); - }, - "removes an attribute as a function": function(body) { - body.attr("bgcolor", "red").attr("bgcolor", function() { return null; }); - assert.isNull(body.attr("bgcolor")); - }, - "removes a namespaced attribute as null": function(body) { - body.attr("xlink:href", "url").attr("xlink:href", null); - assert.isNull(body.attr("bgcolor")); - }, - "removes a namespaced attribute as a function": function(body) { - body.attr("xlink:href", "url").attr("xlink:href", function() { return null; }); - assert.isNull(body.attr("xlink:href")); - }, - "removes attributes as a map of null": function(body) { - body.node().setAttribute("bgcolor", "white"); - body.node().setAttributeNS("http://www.w3.org/1999/xlink", "href", "foo.png"); - body.attr({bgcolor: null, "xlink:href": null}); - assert.isNull(body.node().getAttribute("bgcolor")); - assert.isNull(body.node().getAttributeNS("http://www.w3.org/1999/xlink", "href")); - }, - "removes attributes as a map of functions that return null": function(body) { - body.node().setAttribute("bgcolor", "white"); - body.node().setAttributeNS("http://www.w3.org/1999/xlink", "href", "foo.png"); - body.attr({bgcolor: function() {}, "xlink:href": function() {}}); - assert.isNull(body.node().getAttribute("bgcolor")); - assert.isNull(body.node().getAttributeNS("http://www.w3.org/1999/xlink", "href")); - }, - "returns the current selection": function(body) { - assert.isTrue(body.attr("foo", "bar") === body); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/attr").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "sets an attribute as a string": function(div) { - div.attr("bgcolor", "red"); - assert.equal(div[0][0].getAttribute("bgcolor"), "red"); - assert.equal(div[0][1].getAttribute("bgcolor"), "red"); - }, - "sets an attribute as a number": function(div) { - div.attr("opacity", 0.4); - assert.equal(div[0][0].getAttribute("opacity"), "0.4"); - assert.equal(div[0][1].getAttribute("opacity"), "0.4"); - }, - "sets an attribute as a function": function(div) { - div.attr("bgcolor", function() { return "coral"; }); - assert.equal(div[0][0].getAttribute("bgcolor"), "coral"); - assert.equal(div[0][1].getAttribute("bgcolor"), "coral"); - }, - "sets an attribute as a function of data": function(div) { - div.attr("bgcolor", _.interpolateRgb("brown", "steelblue")); - assert.equal(div[0][0].getAttribute("bgcolor"), "#a52a2a"); - assert.equal(div[0][1].getAttribute("bgcolor"), "#4682b4"); - }, - "sets an attribute as a function of index": function(div) { - div.attr("bgcolor", function(d, i) { return "color-" + i; }); - assert.equal(div[0][0].getAttribute("bgcolor"), "color-0"); - assert.equal(div[0][1].getAttribute("bgcolor"), "color-1"); - }, - "sets a namespaced attribute as a string": function(div) { - div.attr("xlink:href", "url"); - assert.equal(div[0][0].getAttributeNS("http://www.w3.org/1999/xlink", "href"), "url"); - assert.equal(div[0][1].getAttributeNS("http://www.w3.org/1999/xlink", "href"), "url"); - }, - "sets a namespaced attribute as a function": function(div) { - div.data(["red", "blue"]).attr("xlink:href", function(d, i) { return d + "-" + i; }); - assert.equal(div[0][0].getAttributeNS("http://www.w3.org/1999/xlink", "href"), "red-0"); - assert.equal(div[0][1].getAttributeNS("http://www.w3.org/1999/xlink", "href"), "blue-1"); - }, - "gets an attribute value": function(div) { - div[0][0].setAttribute("bgcolor", "purple"); - assert.equal(div.attr("bgcolor"), "purple"); - }, - "gets a namespaced attribute value": function(div) { - div[0][0].setAttributeNS("http://www.w3.org/1999/xlink", "foo", "bar"); - assert.equal(div.attr("xlink:foo"), "bar"); - }, - "removes an attribute as null": function(div) { - div.attr("href", "url").attr("href", null); - assert.isNull(div[0][0].getAttribute("href")); - assert.isNull(div[0][1].getAttribute("href")); - }, - "removes an attribute as a function": function(div) { - div.attr("href", "url").attr("href", function() { return null; }); - assert.isNull(div[0][0].getAttribute("href")); - assert.isNull(div[0][1].getAttribute("href")); - }, - "removes a namespaced attribute as null": function(div) { - div.attr("xlink:foo", "bar").attr("xlink:foo", null); - assert.isNull(div[0][0].getAttributeNS("http://www.w3.org/1999/xlink", "foo")); - assert.isNull(div[0][1].getAttributeNS("http://www.w3.org/1999/xlink", "foo")); - }, - "removes a namespaced attribute as a function": function(div) { - div.attr("xlink:foo", "bar").attr("xlink:foo", function() { return null; }); - assert.isNull(div[0][0].getAttributeNS("http://www.w3.org/1999/xlink", "foo")); - assert.isNull(div[0][1].getAttributeNS("http://www.w3.org/1999/xlink", "foo")); - }, - "returns the current selection": function(div) { - assert.isTrue(div.attr("foo", "bar") === div); - }, - "ignores null nodes": function(div) { - var node = div[0][1]; - div.attr("href", null); - div[0][1] = null; - div.attr("href", "url"); - assert.equal(div[0][0].getAttribute("href"), "url"); - assert.isNull(node.getAttribute("href")); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/call-test.js b/test/selection/call-test.js deleted file mode 100644 index 94191468d457e9..00000000000000 --- a/test/selection/call-test.js +++ /dev/null @@ -1,75 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.call"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/call").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "calls the function once": function(body) { - var count = 0; - body.call(function() { ++count; }); - assert.equal(count, 1); - }, - "passes any optional arguments": function(body) { - var abc; - body.call(function(selection, a, b, c) { abc = [a, b, c]; }, "a", "b", "c"); - assert.deepEqual(abc, ["a", "b", "c"]); - }, - "passes the selection as the first argument": function(body) { - var s; - body.call(function(selection) { s = selection; }); - assert.isTrue(s === body); - }, - "uses the selection as the context": function(body) { - var s; - body.call(function() { s = this; }); - assert.isTrue(s === body); - }, - "returns the current selection": function(body) { - assert.isTrue(body.call(function() {}) === body); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/call").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "calls the function once": function(div) { - var count = 0; - div.call(function() { ++count; }); - assert.equal(count, 1); - }, - "passes any optional arguments": function(div) { - var abc; - div.call(function(selection, a, b, c) { abc = [a, b, c]; }, "a", "b", "c"); - assert.deepEqual(abc, ["a", "b", "c"]); - }, - "passes the selection as the first argument": function(div) { - var s; - div.call(function(selection) { s = selection; }); - assert.isTrue(s === div); - }, - "uses the selection as the context": function(div) { - var s; - div.call(function() { s = this; }); - assert.isTrue(s === div); - }, - "returns the current selection": function(div) { - assert.isTrue(div.call(function() {}) === div); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/classed-test.js b/test/selection/classed-test.js deleted file mode 100644 index 38aec7e47c8de8..00000000000000 --- a/test/selection/classed-test.js +++ /dev/null @@ -1,269 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.classed"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/classed").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "adds a missing class as true": function(body) { - body.attr("class", null); - body.classed("foo", true); - assert.equal(body.node().className, "foo"); - body.classed("bar", true); - assert.equal(body.node().className, "foo bar"); - }, - "removes an existing class as false": function(body) { - body.attr("class", "bar foo"); - body.classed("foo", false); - assert.equal(body.node().className, "bar"); - body.classed("bar", false); - assert.equal(body.node().className, ""); - }, - "preserves an existing class as true": function(body) { - body.attr("class", "bar foo"); - body.classed("foo", true); - assert.equal(body.node().className, "bar foo"); - body.classed("bar", true); - assert.equal(body.node().className, "bar foo"); - }, - "preserves a missing class as false": function(body) { - body.attr("class", "baz"); - body.classed("foo", false); - assert.equal(body.node().className, "baz"); - body.attr("class", null); - body.classed("bar", false); - assert.equal(body.node().className, ""); - }, - "gets an existing class": function(body) { - body.attr("class", " foo\tbar baz"); - assert.isTrue(body.classed("foo")); - assert.isTrue(body.classed("bar")); - assert.isTrue(body.classed("baz")); - }, - "does not get a missing class": function(body) { - body.attr("class", " foo\tbar baz"); - assert.isFalse(body.classed("foob")); - assert.isFalse(body.classed("bare")); - assert.isFalse(body.classed("rbaz")); - }, - "accepts a name with whitespace, collapsing it": function(body) { - body.attr("class", null); - body.classed(" foo\t", true); - assert.equal(body.node().className, "foo"); - body.classed("\tfoo ", false); - assert.equal(body.node().className, ""); - }, - "accepts a name with multiple classes separated by whitespace": function(body) { - body.attr("class", null); - body.classed("foo bar", true); - assert.equal(body.node().className, "foo bar"); - assert.isTrue(body.classed("foo bar")); - assert.isTrue(body.classed("bar foo")); - assert.isFalse(body.classed("foo bar baz")); - assert.isFalse(body.classed("foob bar")); - body.classed("bar foo", false); - assert.equal(body.node().className, ""); - }, - "accepts a silly class name with unsafe characters": function(body) { - body.attr("class", null); - body.classed("foo.bar", true); - assert.equal(body.node().className, "foo.bar"); - assert.isTrue(body.classed("foo.bar")); - assert.isFalse(body.classed("foo")); - assert.isFalse(body.classed("bar")); - body.classed("bar.foo", false); - assert.equal(body.node().className, "foo.bar"); - body.classed("foo.bar", false); - assert.equal(body.node().className, ""); - }, - "accepts a name with duplicate classes, ignoring them": function(body) { - body.attr("class", null); - body.classed(" foo\tfoo ", true); - assert.equal(body.node().className, "foo"); - body.classed("\tfoo foo ", false); - assert.equal(body.node().className, ""); - }, - "accepts a value function returning true or false": function(body) { - body.attr("class", null); - body.classed("foo", function() { return true; }); - assert.equal(body.node().className, "foo"); - body.classed("foo bar", function() { return true; }); - assert.equal(body.node().className, "foo bar"); - body.classed("foo", function() { return false; }); - assert.equal(body.node().className, "bar"); - }, - "accepts a name object containing true or false": function(body) { - body.attr("class", null); - body.classed({foo: true}); - assert.equal(body.node().className, "foo"); - body.classed({bar: true, foo: false}); - assert.equal(body.node().className, "bar"); - }, - "accepts a name object containing a function returning true or false": function(body) { - body.attr("class", null); - body.classed({foo: function() { return true; }}); - assert.equal(body.node().className, "foo"); - }, - "accepts a name object containing a mix of functions and non-functions": function(body) { - body.attr("class", "foo"); - body.classed({foo: false, bar: function() { return true; }}); - assert.equal(body.node().className, "bar"); - }, - "the value may be truthy or falsey": function(body) { - body.attr("class", "foo"); - body.classed({foo: null, bar: function() { return 1; }}); - assert.equal(body.node().className, "bar"); - }, - "keys in the name object may contain whitespace": function(body) { - body.attr("class", null); - body.classed({" foo\t": function() { return true; }}); - assert.equal(body.node().className, "foo"); - body.attr("class", null); - }, - "keys in the name object may reference multiple classes": function(body) { - body.attr("class", null); - body.classed({"foo bar": function() { return true; }}); - assert.equal(body.node().className, "foo bar"); - body.attr("class", null); - }, - "keys in the name object may contain duplicates": function(body) { - body.attr("class", null); - body.classed({"foo foo": function() { return true; }}); - assert.equal(body.node().className, "foo"); - body.attr("class", null); - }, - "value functions are only evaluated once when used for multiple classes": function(body) { - var count = 0; - body.attr("class", null); - body.classed({"foo bar": function() { return ++count; }}); - assert.equal(body.node().className, "foo bar"); - assert.equal(count, 1); - }, - "returns the current selection": function(body) { - assert.isTrue(body.classed("foo", true) === body); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/classed").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "adds a missing class as true": function(div) { - div.attr("class", null); - div.classed("foo", true); - assert.equal(div[0][0].className, "foo"); - assert.equal(div[0][1].className, "foo"); - div.classed("bar", true); - assert.equal(div[0][0].className, "foo bar"); - assert.equal(div[0][1].className, "foo bar"); - }, - "adds a missing class as a function": function(div) { - div.data([0, 1]).attr("class", null); - div.classed("foo", function(d, i) { return d === 0; }); - assert.equal(div[0][0].className, "foo"); - assert.equal(div[0][1].className, ""); - div.classed("bar", function(d, i) { return i === 1; }); - assert.equal(div[0][0].className, "foo"); - assert.equal(div[0][1].className, "bar"); - }, - "removes an existing class as false": function(div) { - div.attr("class", "bar foo"); - div.classed("foo", false); - assert.equal(div[0][0].className, "bar"); - assert.equal(div[0][1].className, "bar"); - div.classed("bar", false); - assert.equal(div[0][0].className, ""); - assert.equal(div[0][1].className, ""); - }, - "removes an existing class as a function": function(div) { - div.data([0, 1]).attr("class", "bar foo"); - div.classed("foo", function(d, i) { return d === 0; }); - assert.equal(div[0][0].className, "bar foo"); - assert.equal(div[0][1].className, "bar"); - div.classed("bar", function(d, i) { return i === 1; }); - assert.equal(div[0][0].className, "foo"); - assert.equal(div[0][1].className, "bar"); - div.classed("foo", function() { return false; }); - assert.equal(div[0][0].className, ""); - assert.equal(div[0][1].className, "bar"); - div.classed("bar", function() { return false; }); - assert.equal(div[0][0].className, ""); - assert.equal(div[0][1].className, ""); - }, - "preserves an existing class as true": function(div) { - div.attr("class", "bar foo"); - div.classed("foo", true); - assert.equal(div[0][0].className, "bar foo"); - assert.equal(div[0][1].className, "bar foo"); - div.classed("bar", true); - assert.equal(div[0][0].className, "bar foo"); - assert.equal(div[0][1].className, "bar foo"); - }, - "preserves an existing class as a function": function(div) { - div.attr("class", "bar foo"); - div.classed("foo", function() { return true; }); - assert.equal(div[0][0].className, "bar foo"); - assert.equal(div[0][1].className, "bar foo"); - div.classed("bar", function() { return true; }); - assert.equal(div[0][0].className, "bar foo"); - assert.equal(div[0][1].className, "bar foo"); - }, - "preserves a missing class as false": function(div) { - div.attr("class", "baz"); - div.classed("foo", false); - assert.equal(div[0][0].className, "baz"); - assert.equal(div[0][1].className, "baz"); - div.attr("class", null); - div.classed("bar", false); - assert.equal(div[0][0].className, ""); - assert.equal(div[0][1].className, ""); - }, - "preserves a missing class as a function": function(div) { - div.attr("class", "baz"); - div.classed("foo", function() { return false; }); - assert.equal(div[0][0].className, "baz"); - assert.equal(div[0][1].className, "baz"); - div.attr("class", null); - div.classed("bar", function() { return false; }); - assert.equal(div[0][0].className, ""); - assert.equal(div[0][1].className, ""); - }, - "gets an existing class": function(div) { - div[0][0].className = " foo\tbar baz"; - assert.isTrue(div.classed("foo")); - assert.isTrue(div.classed("bar")); - assert.isTrue(div.classed("baz")); - }, - "does not get a missing class": function(div) { - div[0][0].className = " foo\tbar baz"; - assert.isFalse(div.classed("foob")); - assert.isFalse(div.classed("bare")); - assert.isFalse(div.classed("rbaz")); - }, - "returns the current selection": function(div) { - assert.isTrue(div.classed("foo", true) === div); - }, - "ignores null nodes": function(div) { - var node = div[0][1]; - div.attr("class", null); - div[0][1] = null; - div.classed("foo", true); - assert.equal(div[0][0].className, "foo"); - assert.equal(node.className, ""); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/data-test.js b/test/selection/data-test.js deleted file mode 100644 index c607ed6c1566c8..00000000000000 --- a/test/selection/data-test.js +++ /dev/null @@ -1,270 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.data"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "assigns data as an array": function(body) { - var data = new Object(); - body.data([data]); - assert.strictEqual(body.node().__data__, data); - }, - "assigns data as a function": function(body) { - var data = new Object(); - body.data(function() { return [data]; }); - assert.strictEqual(body.node().__data__, data); - }, - "stores data in the DOM": function(body) { - var expected = new Object(), actual; - body.node().__data__ = expected; - body.each(function(d) { actual = d; }); - assert.strictEqual(actual, expected); - }, - "returns a new selection": function(body) { - assert.isFalse(body.data([1]) === body); - }, - "with no arguments, returns an array of data": function(body) { - var data = new Object(); - body.data([data]); - assert.deepEqual(body.data(), [data]); - assert.strictEqual(body.data()[0], data); - }, - "throws an error if data is null": function(body) { - var errored; - try { body.data(null); } catch (e) { errored = true; } - assert.isTrue(errored); - }, - "throws an error if data is a function that returns null": function(body) { - var errored; - try { body.data(function() {}); } catch (e) { errored = true; } - assert.isTrue(errored); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/data").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "assigns data as an array": function(div) { - var a = new Object(), b = new Object(); - div.data([a, b]); - assert.strictEqual(div[0][0].__data__, a); - assert.strictEqual(div[0][1].__data__, b); - }, - "assigns data as a function": function(div) { - var a = new Object(), b = new Object(); - div.data(function() { return [a, b]; }); - assert.strictEqual(div[0][0].__data__, a); - assert.strictEqual(div[0][1].__data__, b); - }, - "stores data in the DOM": function(div) { - var a = new Object(), b = new Object(), actual = []; - div[0][0].__data__ = a; - div[0][1].__data__ = b; - div.each(function(d) { actual.push(d); }); - assert.deepEqual(actual, [a, b]); - }, - "returns a new selection": function(div) { - assert.isFalse(div.data([0, 1]) === div); - }, - "throws an error if data is null": function(div) { - var errored; - try { div.data(null); } catch (e) { errored = true; } - assert.isTrue(errored); - }, - "throws an error if data is a function that returns null": function(div) { - var errored; - try { div.data(function() {}); } catch (e) { errored = true; } - assert.isTrue(errored); - }, - "with no arguments, returns an array of data": function(div) { - var a = new Object(), b = new Object(), actual = []; - div[0][0].__data__ = a; - div[0][1].__data__ = b; - assert.deepEqual(div.data(), [a, b]); - }, - "with no arguments, returned array has undefined for null nodes": function(div) { - var b = new Object(), actual = []; - div[0][0] = null; - div[0][1].__data__ = b; - var data = div.data(); - assert.isUndefined(data[0]); - assert.strictEqual(data[1], b); - assert.equal(data.length, 2); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/data").document(), - "on a simple page": { - "ignores duplicate keys in both data and selection": function(d3) { - var div = d3.select("body").html("").selectAll("div") - .data(["aa", "ab", "ac", "ba", "bb", "bc"]) - .enter().append("div") - .text(function(d) { return d; }); - - var update = div.data(["aa", "ab", "ba", "bb"], function(d) { return d.substring(0, 1); }), - enter = update.enter(), - exit = update.exit(); - - assert.equal(update.length, 1); - - // enter - [ null, null, null, null] - assert.equal(enter[0].length, 4); - assert.equal(enter[0][0], null); - assert.equal(enter[0][1], null); - assert.equal(enter[0][2], null); - assert.equal(enter[0][3], null); - - // update - [ aa (a), null, ba (b), null] - assert.equal(update[0].length, 4); - assert.strictEqual(update[0][0], div[0][0]); - assert.equal(update[0][1], null); - assert.strictEqual(update[0][2], div[0][3]); - assert.equal(update[0][3], null); - - // exit - [ null, ab (a), ac (a), null, bb (b), bc (b)] - assert.equal(exit[0].length, 6); - assert.equal(exit[0][0], null); - assert.strictEqual(exit[0][1], div[0][1]); - assert.strictEqual(exit[0][2], div[0][2]); - assert.equal(exit[0][3], null); - assert.strictEqual(exit[0][4], div[0][4]); - assert.strictEqual(exit[0][5], div[0][5]); - } - } - } -}); - -suite.addBatch({ - "selectAll(div).selectAll(span)": { - topic: load("selection/data").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div") - .data([0, 1]) - .enter().append("div").selectAll("span") - .data([0, 1]) - .enter().append("span"); - }, - "assigns data as an array": function(span) { - var a = new Object(), b = new Object(); - span.data([a, b]); - assert.strictEqual(span[0][0].__data__, a); - assert.strictEqual(span[0][1].__data__, b); - assert.strictEqual(span[1][0].__data__, a); - assert.strictEqual(span[1][1].__data__, b); - }, - "assigns data as a function": function(span) { - var a = new Object(), b = new Object(), c = new Object(), d = new Object(); - span.data(function(z, i) { return i ? [c, d] : [a, b]; }); - assert.strictEqual(span[0][0].__data__, a); - assert.strictEqual(span[0][1].__data__, b); - assert.strictEqual(span[1][0].__data__, c); - assert.strictEqual(span[1][1].__data__, d); - }, - "evaluates the function once per group": function(span) { - var count = 0; - span.data(function() { ++count; return [0, 1]; }); - assert.equal(count, 2); - }, - "defines an update selection for updating data": function(span) { - var update = span.data([0, 1, 2, 3]); - assert.equal(update.length, 2); - assert.equal(update[0].length, 4); - assert.equal(update[1].length, 4); - assert.domEqual(update[0][0], span[0][0]); - assert.domEqual(update[0][1], span[0][1]); - assert.domNull(update[0][2]); - assert.domNull(update[0][3]); - assert.domEqual(update[1][0], span[1][0]); - assert.domEqual(update[1][1], span[1][1]); - assert.domNull(update[1][2]); - assert.domNull(update[1][3]); - }, - "defines an enter selection for entering data": function(span) { - var enter = span.data([0, 1, 2, 3]).enter(); - assert.isFalse(enter.empty()); - assert.equal(enter.length, 2); - assert.equal(enter[0].length, 4); - assert.equal(enter[1].length, 4); - assert.domNull(enter[0][0]); - assert.domNull(enter[0][1]); - assert.deepEqual(enter[0][2], {__data__: 2}); - assert.deepEqual(enter[0][3], {__data__: 3}); - assert.domNull(enter[1][0]); - assert.domNull(enter[1][1]); - assert.deepEqual(enter[1][2], {__data__: 2}); - assert.deepEqual(enter[1][3], {__data__: 3}); - }, - "defines an exit selection for exiting data": function(span) { - var exit = span.data([0]).exit(); - assert.isFalse(exit.empty()); - assert.equal(exit.length, 2); - assert.equal(exit[0].length, 2); - assert.equal(exit[1].length, 2); - assert.domNull(exit[0][0]); - assert.domEqual(exit[0][1], span[0][1]); - assert.domNull(exit[1][0]); - assert.domEqual(exit[1][1], span[1][1]); - }, - "observes the specified key function": function(span) { - var update = span.data([1, 2], Number); - assert.isFalse(update.empty()); - assert.equal(update.length, 2); - assert.equal(update[0].length, 2); - assert.equal(update[1].length, 2); - assert.domEqual(update[0][0], span[0][1]); - assert.domNull(update[0][1]); - assert.domEqual(update[1][0], span[1][1]); - assert.domNull(update[1][1]); - - var enter = update.enter(); - assert.equal(enter.length, 2); - assert.equal(enter[0].length, 2); - assert.equal(enter[1].length, 2); - assert.domNull(enter[0][0]); - assert.deepEqual(enter[0][1], {__data__: 2}); - assert.domNull(enter[1][0]); - assert.deepEqual(enter[1][1], {__data__: 2}); - - var exit = update.exit(); - assert.equal(exit.length, 2); - assert.equal(exit[0].length, 2); - assert.equal(exit[1].length, 2); - assert.domEqual(exit[0][0], span[0][0]); - assert.domNull(exit[0][1]); - assert.domEqual(exit[1][0], span[1][0]); - assert.domNull(exit[1][1]); - }, - "handles keys that are in the default object's prototype chain": function(span) { - // This also applies to the non-standard "watch" and "unwatch" in Mozilla Firefox. - var update = span.data(["hasOwnProperty", "isPrototypeOf", "toLocaleString", "toString", "valueOf"], String); - assert.domNull(update[0][0]); - assert.domNull(update[0][1]); - assert.domNull(update[0][2]); - assert.domNull(update[0][3]); - assert.domNull(update[0][4]); - // This throws an error if Object.hasOwnProperty isn't used. - span.data([0], function() { return "hasOwnProperty"; }); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/datum-test.js b/test/selection/datum-test.js deleted file mode 100644 index 457c8e5328705b..00000000000000 --- a/test/selection/datum-test.js +++ /dev/null @@ -1,87 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.datum"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/datum").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "updates the data according to the specified function": function(body) { - body.data([42]).datum(function(d, i) { return d + i; }); - assert.equal(body.node().__data__, 42); - }, - "updates the data to the specified constant": function(body) { - body.datum(43); - assert.equal(body.node().__data__, 43); - }, - "deletes the data if the function returns null": function(body) { - body.data([42]).datum(function() { return null; }); - assert.isFalse("__data__" in body.node()); - }, - "deletes the data if the constant is null": function(body) { - body.data([42]).datum(null); - assert.isFalse("__data__" in body.node()); - }, - "returns the current selection": function(body) { - assert.isTrue(body.datum(function() { return 1; }) === body); - assert.isTrue(body.datum(2) === body); - }, - "with no arguments, returns the first node's datum": function(body) { - body.data([42]); - assert.equal(body.datum(), 42); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/datum").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "updates the data according to the specified function": function(div) { - div.data([42, 43]).datum(function(d, i) { return d + i; }); - assert.equal(div[0][0].__data__, 42); - assert.equal(div[0][1].__data__, 44); - }, - "updates the data to the specified constant": function(div) { - div.datum(44); - assert.equal(div[0][0].__data__, 44); - assert.equal(div[0][1].__data__, 44); - }, - "deletes the data if the function returns null": function(div) { - div.datum(function() { return null; }); - assert.isFalse("__data__" in div[0][0]); - assert.isFalse("__data__" in div[0][1]); - }, - "deletes the data if the constant is null": function(div) { - div.datum(null); - assert.isFalse("__data__" in div[0][0]); - assert.isFalse("__data__" in div[0][1]); - }, - "returns the current selection": function(div) { - assert.isTrue(div.datum(function() { return 1; }) === div); - assert.isTrue(div.datum(2) === div); - }, - "ignores null nodes": function(div) { - var node = div[0][1]; - div[0][1] = null; - div.datum(function() { return 1; }); - assert.equal(div[0][0].__data__, 1); - assert.equal(node.__data__, 2); - div.datum(43); - assert.equal(div[0][0].__data__, 43); - assert.equal(node.__data__, 2); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/each-test.js b/test/selection/each-test.js deleted file mode 100644 index e1d130845deb80..00000000000000 --- a/test/selection/each-test.js +++ /dev/null @@ -1,87 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.each"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/each").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "calls the function once per element": function(body) { - var count = 0; - body.each(function() { ++count; }); - assert.equal(count, 1); - }, - "passes the data and index to the function": function(body) { - var data = new Object(), dd, ii; - body.data([data]).each(function(d, i) { dd = d; ii = i; }); - assert.isTrue(dd === data); - assert.isTrue(ii === 0); - }, - "uses the node as the context": function(body) { - var node; - body.each(function() { node = this; }); - assert.isTrue(node === body.node()); - }, - "returns the same selection": function(body) { - assert.isTrue(body.each(function() {}) === body); - }, - "returns the current selection": function(body) { - assert.isTrue(body.each(function() {}) === body); - }, - "ignores null nodes": function(body) { - var count = 0; - body[0][0] = null; - body.each(function() { ++count; }); - assert.equal(count, 0); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/each").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "calls the function once per element": function(div) { - var count = 0; - div.each(function() { ++count; }); - assert.equal(count, 2); - }, - "passes the data and index to the function": function(div) { - var data = [new Object(), new Object()], dd = [], ii = []; - div.data(data).each(function(d, i) { dd.push(d); ii.push(i); }); - assert.deepEqual(dd, data); - assert.deepEqual(ii, [0, 1]); - }, - "uses the node as the context": function(div) { - var nodes = []; - div.each(function() { nodes.push(this); }); - assert.equal(nodes.length, 2); - assert.isTrue(div[0][0] == nodes[0]); - assert.isTrue(div[0][1] == nodes[1]); - }, - "returns the same selection": function(div) { - assert.isTrue(div.each(function() {}) === div); - }, - "returns the current selection": function(div) { - assert.isTrue(div.each(function() {}) === div); - }, - "ignores null nodes": function(div) { - var count = 0; - div[0][0] = null; - div.each(function() { ++count; }); - assert.equal(count, 1); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/empty-test.js b/test/selection/empty-test.js deleted file mode 100644 index 70cda7763d2aeb..00000000000000 --- a/test/selection/empty-test.js +++ /dev/null @@ -1,53 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.empty"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/empty").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "returns true for empty selections": function(body) { - assert.isTrue(body.select("foo").empty()); - }, - "returns false for non-empty selections": function(body) { - assert.isFalse(body.empty()); - }, - "ignores null nodes": function(body) { - body[0][0] = null; - assert.isTrue(body.empty()); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/empty").document(), - "on a simple page": { - topic: function(d3) { - var body = d3.select("body"); - body.append("div").append("span"); - body.append("div"); - return body.selectAll("div"); - }, - "returns true for empty selections": function(div) { - assert.isTrue(div.select("foo").empty()); - }, - "returns false for non-empty selections": function(div) { - assert.isFalse(div.empty()); - assert.isFalse(div.select("span").empty()); - }, - "ignores null nodes": function(div) { - div[0][0] = null; - assert.isTrue(div.select("span").empty()); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/enter-test.js b/test/selection/enter-test.js deleted file mode 100644 index 4f0ab404149161..00000000000000 --- a/test/selection/enter-test.js +++ /dev/null @@ -1,24 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.enter"); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/enter").document(), - "is an instanceof d3.selection.enter": function(d3) { - var enter = d3.select("body").selectAll("div").data([0, 1]).enter(); - assert.instanceOf(enter, d3.selection.enter); - }, - "selection prototype can be extended": function(d3) { - var enter = d3.select("body").html("").selectAll("div").data([0, 1]).enter(); - d3.selection.enter.prototype.foo = function() { return this.append("foo"); }; - var selection = enter.foo(); - assert.equal(d3.select("body").html(), ""); - delete d3.selection.enter.prototype.foo; - } - } -}); - -suite.export(module); diff --git a/test/selection/filter-test.js b/test/selection/filter-test.js deleted file mode 100644 index e1fdbcd49fd136..00000000000000 --- a/test/selection/filter-test.js +++ /dev/null @@ -1,72 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.filter"); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/filter").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div") - .data([0, 1]) - .enter().append("div") - .selectAll("span") - .data(function(d) { d <<= 1; return [d, d + 1]; }) - .enter().append("span"); - }, - "preserves matching elements": function(span) { - var some = span.filter(function(d, i) { return i === 0; }); - assert.isTrue(some[0][0] === span[0][0]); - assert.isTrue(some[1][0] === span[1][0]); - }, - "removes non-matching elements": function(span) { - var some = _.merge(span.filter(function(d, i) { return d & 1; })); - assert.equal(some.indexOf(span[0][0]), -1); - assert.equal(some.indexOf(span[1][0]), -1); - }, - "preserves data": function(span) { - var some = span.filter(function(d, i) { return d & 1; }); - assert.equal(some[0][0].__data__, 1); - assert.equal(some[1][0].__data__, 3); - }, - "preserves grouping": function(span) { - var some = span.filter(function(d, i) { return d & 1; }); - assert.equal(some.length, 2); - assert.equal(some[0].length, 1); - assert.equal(some[1].length, 1); - }, - "preserves parent node": function(span) { - var some = span.filter(function(d, i) { return d & 1; }); - assert.isTrue(some[0].parentNode === span[0].parentNode); - assert.isTrue(some[1].parentNode === span[1].parentNode); - }, - "does not preserve index": function(span) { - var indexes = []; - span.filter(function(d, i) { return d & 1; }).each(function(d, i) { indexes.push(i); }); - assert.deepEqual(indexes, [0, 0]); - }, - "can be specified as a selector": function(span) { - span.classed("foo", function(d, i) { return d & 1; }); - var some = span.filter(".foo"); - assert.equal(some.length, 2); - assert.equal(some[0].length, 1); - assert.equal(some[1].length, 1); - }, - "returns a new selection": function(span) { - assert.isFalse(span.filter(function() { return 1; }) === span); - }, - "ignores null nodes": function(span) { - var node = span[0][1]; - span[0][1] = null; - var some = span.filter(function(d, i) { return d & 1; }); - assert.isTrue(some[0][0] === span[0][3]); - assert.equal(some.length, 2); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/html-test.js b/test/selection/html-test.js deleted file mode 100644 index e737d190fa7a21..00000000000000 --- a/test/selection/html-test.js +++ /dev/null @@ -1,134 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.html"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "sets the inner HTML as a string": function(body) { - body.html("

Hello, world!

"); - assert.equal(body.node().firstChild.tagName, "H1"); - assert.equal(body.node().firstChild.textContent, "Hello, world!"); - }, - "sets the inner HTML as a number": function(body) { - body.html(42); - assert.equal(body.node().innerHTML, "42"); - assert.equal(body.node().firstChild.nodeType, 3); - }, - "sets the inner HTML as a function": function(body) { - body.data(["Subject"]).html(function(d, i) { return "" + d + "" + i + ""; }); - assert.equal(body.node().firstChild.tagName, "B"); - assert.equal(body.node().firstChild.textContent, "Subject"); - assert.equal(body.node().lastChild.tagName, "I"); - assert.equal(body.node().lastChild.textContent, "0"); - }, - "clears the inner HTML as null": function(body) { - body.html(null); - assert.equal(body.node().innerHTML, ""); - assert.isNull(body.node().firstChild); - }, - "clears the inner HTML as undefined": function(body) { - body.html(undefined); - assert.equal(body.node().innerHTML, ""); - assert.isNull(body.node().firstChild); - }, - "clears the inner HTML as the empty string": function(body) { - body.html(""); - assert.equal(body.node().innerHTML, ""); - assert.isNull(body.node().firstChild); - }, - "clears the inner HTML as a function returning the empty string": function(body) { - body.text(function() { return ""; }); - assert.equal(body.node().innerHTML, ""); - assert.isNull(body.node().firstChild); - }, - "clears the inner HTML as a function returning null": function(body) { - body.text(function() { return null; }); - assert.equal(body.node().innerHTML, ""); - assert.isNull(body.node().firstChild); - }, - "clears the inner HTML as a function returning undefined": function(body) { - body.text(function() { return undefined; }); - assert.equal(body.node().innerHTML, ""); - assert.isNull(body.node().firstChild); - }, - "returns the current selection": function(body) { - assert.isTrue(body.html("foo") === body); - }, - "ignores null nodes": function(body) { - var node = body.node(); - body[0][0] = null; - node.innerHTML = "

foo

"; - body.html("bar"); - assert.equal(node.textContent, "foo"); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "sets the inner HTML as a string": function(div) { - div.html("

Hello, world!

"); - assert.equal(div[0][0].firstChild.tagName, "H1"); - assert.equal(div[0][0].firstChild.textContent, "Hello, world!"); - assert.equal(div[0][1].firstChild.tagName, "H1"); - assert.equal(div[0][1].firstChild.textContent, "Hello, world!"); - }, - "sets the inner HTML as a number": function(div) { - div.html(42); - assert.equal(div[0][0].innerHTML, "42"); - assert.equal(div[0][0].firstChild.nodeType, 3); - }, - "sets the inner HTML as a function": function(div) { - div.data(["foo", "bar"]).html(function(d, i) { return "" + d + "" + i + ""; }); - assert.equal(div[0][0].firstChild.tagName, "B"); - assert.equal(div[0][0].firstChild.textContent, "foo"); - assert.equal(div[0][0].lastChild.tagName, "I"); - assert.equal(div[0][0].lastChild.textContent, "0"); - assert.equal(div[0][1].firstChild.tagName, "B"); - assert.equal(div[0][1].firstChild.textContent, "bar"); - assert.equal(div[0][1].lastChild.tagName, "I"); - assert.equal(div[0][1].lastChild.textContent, "1"); - }, - "clears the inner HTML as null": function(div) { - div.html(null); - assert.equal(div[0][0].innerHTML, ""); - assert.isNull(div[0][0].firstChild); - assert.equal(div[0][1].innerHTML, ""); - assert.isNull(div[0][1].firstChild); - }, - "clears the inner HTML as a function": function(div) { - div.html(function() { return ""; }); - assert.equal(div[0][0].innerHTML, ""); - assert.isNull(div[0][0].firstChild); - assert.equal(div[0][1].innerHTML, ""); - assert.isNull(div[0][1].firstChild); - }, - "returns the current selection": function(div) { - assert.isTrue(div.html("foo") === div); - }, - "ignores null nodes": function(div) { - var node = div[0][0]; - div[0][0] = null; - node.innerHTML = "

foo

"; - div.html("bar"); - assert.equal(node.textContent, "foo"); - assert.equal(div[0][1].textContent, "bar"); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/insert-test.js b/test/selection/insert-test.js deleted file mode 100644 index 2294d3f35c6a04..00000000000000 --- a/test/selection/insert-test.js +++ /dev/null @@ -1,169 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.insert"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/insert").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "inserts before the specified selector": function(body) { - var span = body.html("").append("span"); - var div = body.insert("div", "span"); - assert.equal(div[0][0].tagName, "DIV"); - assert.isNull(div[0][0].namespaceURI); - assert.domEqual(div[0][0], body.node().firstChild); - assert.domEqual(div[0][0].nextSibling, span[0][0]); - }, - "inserts before the specified node": function(body) { - var span = body.html("").append("span"); - var div = body.insert("div", function() { return span.node(); }); - assert.equal(div[0][0].tagName, "DIV"); - assert.isNull(div[0][0].namespaceURI); - assert.domEqual(div[0][0], body.node().firstChild); - assert.domEqual(div[0][0].nextSibling, span[0][0]); - }, - "appends an HTML element": function(body) { - var div = body.insert("div"); - assert.equal(div[0][0].tagName, "DIV"); - assert.isNull(div[0][0].namespaceURI); - assert.domEqual(div[0][0], body.node().lastChild); - }, - "appends an SVG element": function(body) { - var svg = body.insert("svg:svg"); - assert.equal(svg[0][0].tagName, "SVG"); - assert.equal(svg[0][0].namespaceURI, "http://www.w3.org/2000/svg"); - assert.domEqual(svg[0][0].parentNode, body.node()); - assert.domEqual(svg[0][0], body.node().lastChild); - }, - "propagates data to new element": function(body) { - var data = new Object(), div = body.data([data]).insert("div"); - assert.strictEqual(div[0][0].__data__, data); - }, - "returns a new selection": function(body) { - assert.isFalse(body.insert("div") === body); - }, - "inherits namespace from parent node": function(body) { - var g = body.insert("svg:svg").insert("g"); - assert.equal(g[0][0].namespaceURI, "http://www.w3.org/2000/svg"); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().insert("div"); - }, - "appends an HTML element": function(div) { - var span = div.insert("span"); - assert.equal(span[0].length, 2); - assert.equal(span[0][0].tagName, "SPAN"); - assert.equal(span[0][1].tagName, "SPAN"); - assert.isNull(span[0][0].namespaceURI); - assert.isNull(span[0][1].namespaceURI); - assert.domEqual(span[0][0].parentNode, div[0][0]); - assert.domEqual(span[0][1].parentNode, div[0][1]); - assert.domEqual(div[0][0].lastChild, span[0][0]); - assert.domEqual(div[0][1].lastChild, span[0][1]); - }, - "appends an SVG element": function(div) { - var svg = div.insert("svg:svg"); - assert.equal(svg[0].length, 2); - assert.equal(svg[0][0].tagName, "SVG"); - assert.equal(svg[0][1].tagName, "SVG"); - assert.equal(svg[0][0].namespaceURI, "http://www.w3.org/2000/svg"); - assert.equal(svg[0][1].namespaceURI, "http://www.w3.org/2000/svg"); - assert.domEqual(svg[0][0].parentNode, div[0][0]); - assert.domEqual(svg[0][1].parentNode, div[0][1]); - assert.domEqual(div[0][0].lastChild, svg[0][0]); - assert.domEqual(div[0][1].lastChild, svg[0][1]); - }, - "propagates data to new elements": function(div) { - var a = new Object(), b = new Object(), span = div.data([a, b]).insert("span"); - assert.strictEqual(span[0][0].__data__, a); - assert.strictEqual(span[0][1].__data__, b); - }, - "returns a new selection": function(div) { - assert.isFalse(div.insert("div") === div); - }, - "ignores null nodes": function(div) { - div.html(""); - var node = div[0][1]; - div[0][1] = null; - var span = div.insert("span"); - assert.equal(span[0].length, 2); - assert.equal(span[0][0].tagName, "SPAN"); - assert.domNull(span[0][1]); - assert.domEqual(span[0][0].parentNode, div[0][0]); - assert.domEqual(div[0][0].lastChild, span[0][0]); - assert.domNull(node.lastChild); - } - } - } -}); - -suite.addBatch({ - "enter-insert": { - topic: load("selection/selection").document(), - "on a page with existing elements": { - topic: function(d3) { - var body = d3.select("body"); - body.selectAll("div").data(["apple", "orange"]).enter().append("div"); - return body; - }, - "inserts before the following updating sibling": function(body) { - var data = ["peach", "apple", "apple2", "apple3", "banana", "orange", "apricot"]; - body.selectAll("div").data(data, String).enter().insert("div"); - assert.deepEqual(body.selectAll("div").data(), data); - } - } - } -}); - -suite.addBatch({ - "selectAll(div).data(…).enter()": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "inserts before the specified selector": function(body) { - var span = body.append("span"); - var div = body.selectAll("div").data([0, 1]).enter().insert("div", "span"); - assert.equal(div.length, 1); - assert.equal(div[0].length, 2); - assert.domEqual(div[0][0], body.node().firstChild); - assert.domEqual(div[0][1].previousSibling, div[0][0]); - assert.domEqual(div[0][1].nextSibling, span[0][0]); - }, - "propagates data to new elements": function(body) { - var a = new Object(), b = new Object(), div = body.html("").selectAll("div").data([a, b]).enter().insert("div"); - assert.strictEqual(div[0][0].__data__, a); - assert.strictEqual(div[0][1].__data__, b); - }, - "ignores null nodes": function(body) { - body.html("").insert("div"); - var div = body.selectAll("div").data([0, 1, 2]).enter().insert("div"); - assert.equal(div.length, 1); - assert.equal(div[0].length, 3); - assert.domNull(div[0][0]); - assert.domEqual(div[0][1].parentNode, body.node()); - assert.domEqual(div[0][2].parentNode, body.node()); - }, - "returns a new selection": function(body) { - var enter = body.html("").selectAll("div").data([0, 1]).enter(); - assert.isFalse(enter.insert("div") === enter); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/interrupt-test.js b/test/selection/interrupt-test.js deleted file mode 100644 index bb341144201bf9..00000000000000 --- a/test/selection/interrupt-test.js +++ /dev/null @@ -1,32 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.interrupt"); - -suite.addBatch({ - "interrupt": { - topic: load("transition/transition").document(), - "returns the current selection": function(d3) { - var selection = d3.select("body").append("div"); - assert.strictEqual(selection.interrupt(), selection); - }, - "increments the active transition": function(d3) { - var selection = d3.select("body").append("div"), - transition = selection.transition(); - assert.equal(selection.node().__transition__.active, 0); // transition hasn’t yet started - d3.timer.flush(); - assert.equal(selection.node().__transition__.active, transition.id); // transition has started - selection.interrupt(); - assert.equal(selection.node().__transition__.active, transition.id + 1); // transition was interrupted - }, - "does nothing if there is no active transition": function(d3) { - var selection = d3.select("body").append("div"); - assert.isUndefined(selection.node().__transition__); // no transition scheduled - selection.interrupt(); - assert.isUndefined(selection.node().__transition__); // still no transition scheduled - } - } -}); - -suite.export(module); diff --git a/test/selection/node-test.js b/test/selection/node-test.js deleted file mode 100644 index ae6005d0e1a84f..00000000000000 --- a/test/selection/node-test.js +++ /dev/null @@ -1,55 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.node"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/node").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "returns null for empty selections": function(body) { - assert.isNull(body.select("foo").node()); - }, - "returns the first element for non-empty selections": function(body) { - assert.isTrue(body.node() === body[0][0]); - assert.equal(body.node().tagName, "BODY"); - }, - "ignores null nodes": function(body) { - body[0][0] = null; - assert.isNull(body.node()); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/node").document(), - "on a simple page": { - topic: function(d3) { - var body = d3.select("body"); - body.append("div").append("span"); - body.append("div"); - return body.selectAll("div"); - }, - "returns null for empty selections": function(div) { - assert.isNull(div.select("foo").node()); - }, - "returns the first element for non-empty selections": function(div) { - assert.isTrue(div.node() === div[0][0]); - assert.equal(div.node().tagName, "DIV"); - }, - "ignores null nodes": function(div) { - div[0][0] = null; - assert.isTrue(div.node() === div[0][1]); - assert.equal(div.node().tagName, "DIV"); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/on-test.js b/test/selection/on-test.js deleted file mode 100644 index a4d4f8fe90eeec..00000000000000 --- a/test/selection/on-test.js +++ /dev/null @@ -1,135 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.on"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/on").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "registers an event listener for the specified type": function(body) { - var form = body.append("form"), count = 0; - form.on("submit", function() { ++count; }); // jsdom has spotty event support - form.append("input").attr("type", "submit").node().click(); - assert.equal(count, 1); - }, - "replaces an existing event listener for the same type": function(body) { - var form = body.append("form"), count = 0, fail = 0; - form.on("submit", function() { ++fail; }); - form.on("submit", function() { ++count; }); - form.append("input").attr("type", "submit").node().click(); - assert.equal(count, 1); - assert.equal(fail, 0); - }, - "removes an existing event listener": function(body) { - var form = body.append("form"), fail = 0; - form.on("submit", function() { ++fail; }); - form.on("submit", null); - form.append("input").attr("type", "submit").node().click(); - assert.equal(fail, 0); - assert.isUndefined(form.on("submit")); - }, - /* Regrettably, JSDOM ignores the capture flag, so we can't test this yet… - "removing a listener doesn't require the capture flag": function(body) { - var form = body.append("form"), fail = 0; - form.on("submit", function() { ++fail; }, true); - form.on("submit", null); - form.append("input").attr("type", "submit").node().click(); - assert.equal(fail, 0); - assert.isUndefined(form.on("submit")); - }, - */ - "ignores removal of non-matching event listener": function(body) { - body.append("form").on("submit", null); - }, - "observes the specified namespace": function(body) { - var form = body.append("form"), foo = 0, bar = 0; - form.on("submit.foo", function() { ++foo; }); - form.on({"submit.bar": function() { ++bar; }}); - form.append("input").attr("type", "submit").node().click(); - assert.equal(foo, 1); - assert.equal(bar, 1); - }, - "can register listeners as a map": function(body) { - var form = body.append("form"), count = 0, fail = 0; - form.on({submit: function() { ++fail; }}); - form.on({submit: function() { ++count; }}); - form.append("input").attr("type", "submit").node().click(); - assert.equal(count, 1); - assert.equal(fail, 0); - form.on({submit: null}); - assert.isUndefined(form.on("submit")); - }, - /* Not really sure how to test this one… - "observes the specified capture flag": function(body) { - }, - */ - "passes the current data and index to the event listener": function(body) { - var forms = body.html("").selectAll("form").data(["a", "b"]).enter().append("form"), dd, ii, data = new Object(); - forms.on("submit", function(d, i) { dd = d; ii = i; }); - forms.append("input").attr("type", "submit")[0][1].click(); - assert.equal(dd, "b"); - assert.equal(ii, 1); - forms[0][1].__data__ = data; - forms.append("input").attr("type", "submit")[0][1].click(); - assert.equal(dd, data); - assert.equal(ii, 1); - }, - "uses the current element as the context": function(body) { - var forms = body.html("").selectAll("form").data(["a", "b"]).enter().append("form"), context; - forms.on("submit", function() { context = this; }); - forms.append("input").attr("type", "submit")[0][1].click(); - assert.domEqual(context, forms[0][1]); - }, - "returns the current selection": function(body) { - assert.isTrue(body.on("submit", function() {}) === body); - }, - "returns the assigned listener if called with one argument": function(body) { - body.on("mouseover", f).on("click.foo", f); - function f() {} - assert.equal(body.on("mouseover"), f); - assert.equal(body.on("click.foo"), f); - assert.isUndefined(body.on("click")); - assert.isUndefined(body.on("mouseover.foo")); - }, - "omitting the event type": { - "returns undefined when retrieving a listener": function(body) { - assert.isUndefined(body.on(".foo")); - }, - "null removes all named event listeners": function(body) { - body.on("mouseover.foo", f) - .on("click.foo", f) - .on("click.foobar", f) - .on(".foo", null); - function f() {} - assert.isUndefined(body.on("mouseover.foo")); - assert.isUndefined(body.on("click.foo")); - assert.equal(body.on("click.foobar"), f); - }, - "no-op when setting a listener": function(body) { - assert.isTrue(body.on(".foo", function() {}) === body); - assert.isUndefined(body.on(".foo")); - } - } - }, - "sets the current event as d3.event": function(d3) { - var form = d3.select("body").append("form"), event; - form.on("submit", function() { event = d3.event; }); - form.append("input").attr("type", "submit").node().click(); - assert.equal(event.type, "submit"); - assert.domEqual(event.target, form[0][0]); - }, - "restores the original event after notifying listeners": function(d3) { - var form = d3.select("body").append("form"), event = d3.event = new Object(); - form.on("submit", function() {}); - form.append("input").attr("type", "submit").node().click(); - assert.equal(d3.event, event); - } - } -}); - -suite.export(module); diff --git a/test/selection/order-test.js b/test/selection/order-test.js deleted file mode 100644 index 1576d683af13c7..00000000000000 --- a/test/selection/order-test.js +++ /dev/null @@ -1,32 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.order"); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/call").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").selectAll("div") - .data([1, 2, 10, 20]) - .enter().append("div") - .attr("id", String); - }, - "orders elements by data": function(div) { - div = div.data([1, 10, 20, 2], String).order(); - assert.domNull(div[0][0].previousSibling); - assert.domEqual(div[0][1].previousSibling, div[0][0]); - assert.domEqual(div[0][2].previousSibling, div[0][1]); - assert.domEqual(div[0][3].previousSibling, div[0][2]); - assert.domNull(div[0][3].nextSibling); - }, - "returns the current selection": function(span) { - assert.isTrue(span.order() === span); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/property-test.js b/test/selection/property-test.js deleted file mode 100644 index 075f3bd2e37c75..00000000000000 --- a/test/selection/property-test.js +++ /dev/null @@ -1,117 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.property"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/property").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "sets a property as a string": function(body) { - body.property("bgcolor", "red"); - assert.equal(body.node().bgcolor, "red"); - }, - "sets a property as a number": function(body) { - body.property("opacity", 1); - assert.equal(body.node().opacity, "1"); - }, - "sets a property as a function": function(body) { - body.property("bgcolor", function() { return "orange"; }); - assert.equal(body.node().bgcolor, "orange"); - }, - "sets properties as a map of constants": function(body) { - body.property({bgcolor: "purple", opacity: .41}); - assert.equal(body.node().bgcolor, "purple"); - assert.equal(body.node().opacity, .41); - }, - "sets properties as a map of functions": function(body) { - body.data(["cyan"]).property({bgcolor: String, opacity: function(d, i) { return i; }}); - assert.equal(body.node().bgcolor, "cyan"); - assert.equal(body.node().opacity, 0); - }, - "gets a property value": function(body) { - body.node().bgcolor = "yellow"; - assert.equal(body.property("bgcolor"), "yellow"); - }, - "removes a property as null": function(body) { - body.property("bgcolor", "yellow").property("bgcolor", null); - assert.isFalse("bgcolor" in body.node()); - }, - "removes a property as a function": function(body) { - body.property("bgcolor", "yellow").property("bgcolor", function() { return null }); - assert.isFalse("bgcolor" in body.node()); - }, - "removes properties as a map of nulls": function(body) { - body.node().bgcolor = "red"; - body.property({bgcolor: null}); - assert.isFalse("bgcolor" in body.node()); - }, - "removes properties as a map of functions that return null": function(body) { - body.node().bgcolor = "red"; - body.property({bgcolor: function() {}}); - assert.isFalse("bgcolor" in body.node()); - }, - "returns the current selection": function(body) { - assert.isTrue(body.property("bgcolor", "yellow") === body); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/property").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body").html("").selectAll("div").data([0, 1]).enter().append("div"); - }, - "sets a property as a string": function(div) { - div.property("bgcolor", "red"); - assert.equal(div[0][0].bgcolor, "red"); - assert.equal(div[0][1].bgcolor, "red"); - }, - "sets a property as a number": function(div) { - div.property("opacity", 0.4); - assert.equal(div[0][0].opacity, "0.4"); - assert.equal(div[0][1].opacity, "0.4"); - }, - "sets a property as a function": function(div) { - div.property("bgcolor", _.interpolateRgb("brown", "steelblue")); - assert.equal(div[0][0].bgcolor, "#a52a2a"); - assert.equal(div[0][1].bgcolor, "#4682b4"); - }, - "gets a property value": function(div) { - div[0][0].bgcolor = "purple"; - assert.equal(div.property("bgcolor"), "purple"); - }, - "removes a property as null": function(div) { - div.property("bgcolor", "yellow").property("bgcolor", null); - assert.isFalse("bgcolor" in div[0][0]); - assert.isFalse("bgcolor" in div[0][1]); - }, - "removes a property as a function": function(div) { - div.property("bgcolor", "yellow").property("bgcolor", function() { return null }); - assert.isFalse("bgcolor" in div[0][0]); - assert.isFalse("bgcolor" in div[0][1]); - }, - "returns the current selection": function(div) { - assert.isTrue(div.property("bgcolor", "yellow") === div); - }, - "ignores null nodes": function(div) { - var node = div[0][1]; - div.property("bgcolor", null); - div[0][1] = null; - div.property("bgcolor", "red"); - assert.equal(div[0][0].bgcolor, "red"); - assert.isFalse("bgcolor" in node); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/remove-test.js b/test/selection/remove-test.js deleted file mode 100644 index 907bcb40501273..00000000000000 --- a/test/selection/remove-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.remove"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/remove").document(), - "removes the matching elements": function(d3) { - var div = d3.select("body").append("div"); - div.remove(); - assert.domNull(div[0][0].parentNode); - }, - "does not remove non-matching elements": function(d3) { - var body = d3.select("body"), - div1 = body.append("div"), - div2 = body.append("div"); - div1.remove(); - assert.domEqual(div2[0][0].parentNode, body.node()); - }, - "ignores null nodes": function(d3) { - var div1 = d3.select("body").append("div"), - div2 = div1.selectAll("div").data([0, 1]).enter().append("div"), - node = div2[0][0]; - div2[0][0] = null; - div2.remove(); - assert.domEqual(node.parentNode, div1.node()); - assert.domNull(div2[0][1].parentNode); - }, - "returns the current selection": function(d3) { - var div = d3.select("body").append("div"); - assert.isTrue(div.remove() === div); - } - } -}); - -suite.export(module); diff --git a/test/selection/select-test.js b/test/selection/select-test.js deleted file mode 100644 index 33d68bd9b75baa..00000000000000 --- a/test/selection/select-test.js +++ /dev/null @@ -1,69 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.select"); - -suite.addBatch({ - "select": { - topic: load("selection/select").document(), - "on a simple page": { - topic: function(d3) { - var body = d3.select("body"); - body.append("span").attr("class", "f00").attr("id", "b4r").attr("name", "b4z"); - body.append("div").attr("class", "foo").attr("id", "bar").attr("name", "baz"); - return d3; - }, - "selects by element name": function(d3) { - var div = d3.select("div"); - assert.equal(div[0][0].tagName, "DIV"); - }, - "selects by class name": function(d3) { - var div = d3.select(".foo"); - assert.equal(div[0][0].className, "foo"); - }, - "selects by id": function(d3) { - var div = d3.select("div#bar"); - assert.equal(div[0][0].id, "bar"); - }, - "selects by attribute value": function(d3) { - var div = d3.select("[name=baz]"); - assert.equal(div[0][0].getAttribute("name"), "baz"); - }, - "selects by node": function(d3) { - var body = d3.select("body").node(), - div = d3.select(body.lastChild); - assert.isTrue(div[0][0] === body.lastChild); - assert.lengthOf(div, 1); - assert.lengthOf(div[0], 1); - }, - "sets the parentNode to the document element": function(d3) { - var selection = d3.select("body"), - document = d3.selection().node().ownerDocument; - assert.strictEqual(selection[0].parentNode, document.documentElement); - }, - "does not propagate data from the document": function(d3) { - var document = d3.selection().node().ownerDocument; - document.__data__ = 42; - delete document.body.__data__; - try { - assert.isUndefined(d3.select("body").datum()); - } finally { - delete document.__data__; - } - }, - "does not propagate data from the document element": function(d3) { - var document = d3.selection().node().ownerDocument; - document.documentElement.__data__ = 42; - delete document.body.__data__; - try { - assert.isUndefined(d3.select("body").datum()); - } finally { - delete document.documentElement.__data__; - } - } - } - } -}); - -suite.export(module); diff --git a/test/selection/selectAll-test.js b/test/selection/selectAll-test.js deleted file mode 100644 index decbc665fa22d2..00000000000000 --- a/test/selection/selectAll-test.js +++ /dev/null @@ -1,52 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.selectAll"); - -suite.addBatch({ - "selectAll": { - topic: load("selection/selectAll").document(), - "on a simple page": { - topic: function(d3) { - var body = d3.select("body"); - body.append("span").attr("class", "f00").attr("id", "b4r").attr("name", "b4z"); - body.append("div").attr("class", "foo").attr("id", "bar").attr("name", "baz"); - return d3; - }, - "selects by element name": function(d3) { - var div = d3.selectAll("div"); - assert.equal(div[0][0].tagName, "DIV"); - }, - "selects by class name": function(d3) { - var div = d3.selectAll(".foo"); - assert.equal(div[0][0].className, "foo"); - }, - "selects by id": function(d3) { - var div = d3.selectAll("div#bar"); - assert.equal(div[0][0].id, "bar"); - }, - "selects by attribute value": function(d3) { - var div = d3.selectAll("[name=baz]"); - assert.equal(div[0][0].getAttribute("name"), "baz"); - }, - "selects by array": function(d3) { - var body = d3.select("body").node(), div = d3.selectAll([body.lastChild]); - assert.isTrue(div[0][0] === body.lastChild); - assert.lengthOf(div, 1); - assert.lengthOf(div[0], 1); - }, - "groups are arrays, not NodeLists": function(d3) { - var div = d3.select("body").selectAll(function() { return this.getElementsByClassName("div"); }); - assert.isTrue(Array.isArray(div[0])); - }, - "sets the parentNode to the document element": function(d3) { - var selection = d3.selectAll("body"), - document = d3.selection().node().ownerDocument; - assert.strictEqual(selection[0].parentNode, document.documentElement); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/selection-select-test.js b/test/selection/selection-select-test.js deleted file mode 100644 index 082fb7218eb4b8..00000000000000 --- a/test/selection/selection-select-test.js +++ /dev/null @@ -1,128 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.select"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - var body = d3.select("body"); - body.append("div").attr("class", "first"); - body.append("div").attr("class", "second"); - return body; - }, - "selects the first matching element": function(body) { - var div = body.select("div"); - assert.isTrue(div[0][0] === body.node().firstChild); - assert.equal(div.length, 1); - assert.equal(div[0].length, 1); - assert.equal(div.attr("class"), "first"); - }, - "propagates parent node to the selected elements": function(body) { - var div = body.select("div"); - assert.isNotNull(div[0].parentNode); - assert.isTrue(div[0].parentNode === body.node().parentNode); - assert.isTrue(div[0].parentNode === body[0].parentNode); - }, - "propagates data to the selected elements": function(body) { - var data = new Object(), div = body.data([data]).select("div"); - assert.strictEqual(div[0][0].__data__, data); - }, - "does not propagate data if no data was specified": function(body) { - delete body.node().__data__; - var data = new Object(), div = body.select("div").data([data]); - div = body.select("div"); - assert.strictEqual(div[0][0].__data__, data); - assert.isUndefined(body.node().__data__); - }, - "returns null if no match is found": function(body) { - var span = body.select("span"); - assert.equal(span[0][0], null); - assert.equal(span.length, 1); - assert.equal(span[0].length, 1); - }, - "can select via function": function(body) { - body.append("foo"); - var d = {}, dd = [], ii = [], tt = [], - s = body.data([d]).select(function(d, i) { dd.push(d); ii.push(i); tt.push(this); return this.firstChild; }); - assert.deepEqual(dd, [d], "expected data, got {actual}"); - assert.deepEqual(ii, [0], "expected index, got {actual}"); - assert.domEqual(tt[0], body.node(), "expected this, got {actual}"); - assert.domEqual(s[0][0], body.node().firstChild); - delete body.node().__data__; - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - var div = d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - div.append("span").attr("class", "first"); - div.append("span").attr("class", "second"); - return div; - }, - "selects the first matching element": function(div) { - var span = div.select("span"); - assert.isTrue(span[0][0].parentNode === div[0][0]); - assert.isTrue(span[0][1].parentNode === div[0][1]); - assert.equal(span.length, 1); - assert.equal(span[0].length, 2); - assert.equal(span.attr("class"), "first"); - }, - "propagates parent node to the selected elements": function(div) { - var span = div.select("span"); - assert.isNotNull(span[0].parentNode); - assert.isTrue(span[0].parentNode === div.node().parentNode); - assert.isTrue(span[0].parentNode === div[0].parentNode); - }, - "propagates data to the selected elements": function(div) { - var data = new Object(), span = div.data([data]).select("span"); - assert.strictEqual(span[0][0].__data__, data); - }, - "does not propagate data if no data was specified": function(div) { - delete div[0][0].__data__; - delete div[0][1].__data__; - var a = new Object(), b = new Object(), span = div.select("span").data([a, b]); - span = div.select("span"); - assert.strictEqual(span[0][0].__data__, a); - assert.strictEqual(span[0][1].__data__, b); - assert.isUndefined(div[0][0].__data__); - assert.isUndefined(div[0][1].__data__); - }, - "returns null if no match is found": function(div) { - var div = div.select("div"); - assert.equal(div[0][0], null); - assert.equal(div[0][1], null); - assert.equal(div.length, 1); - assert.equal(div[0].length, 2); - }, - "can select via function": function(div) { - var dd = [], ii = [], tt = [], - s = div.data(["a", "b"]).select(function(d, i) { dd.push(d); ii.push(i); tt.push(this); return this.firstChild; }); - assert.deepEqual(dd, ["a", "b"], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.domEqual(tt[0], div[0][0], "expected this, got {actual}"); - assert.domEqual(tt[1], div[0][1], "expected this, got {actual}"); - assert.domEqual(s[0][0], div[0][0].firstChild); - assert.domEqual(s[0][1], div[0][1].firstChild); - }, - "ignores null nodes": function(div) { - div[0][1] = null; - var span = div.select("span"); - assert.equal(span.length, 1); - assert.equal(span[0].length, 2); - assert.isTrue(span[0][0].parentNode === div[0][0]); - assert.isNull(span[0][1]); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/selection-selectAll-test.js b/test/selection/selection-selectAll-test.js deleted file mode 100644 index 1506b5cc9e620f..00000000000000 --- a/test/selection/selection-selectAll-test.js +++ /dev/null @@ -1,131 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.selectAll"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - var body = d3.select("body"); - body.append("div").attr("class", "first"); - body.append("div").attr("class", "second"); - return body; - }, - "selects all matching elements": function(body) { - var div = body.selectAll("div"); - assert.isTrue(div[0][0] === body.node().firstChild); - assert.isTrue(div[0][1] === body.node().lastChild); - assert.equal(div.length, 1); - assert.equal(div[0].length, 2); - }, - "propagates parent node to the selected elements": function(body) { - var div = body.selectAll("div"); - assert.isNotNull(div[0].parentNode); - assert.isTrue(div[0].parentNode === body.node()); - }, - "does not propagate data if data was specified": function(body) { - var div = body.data([new Object()]).selectAll("div"); - assert.isUndefined(div[0][0].__data__); - assert.isUndefined(div[0][1].__data__); - }, - "does not propagate data if data was not specified": function(body) { - var div = body.selectAll("div").data([1, 2]); - div = body.data([new Object()]).selectAll("div"); - assert.equal(div[0][0].__data__, 1); - assert.equal(div[0][1].__data__, 2); - }, - "returns empty array if no match is found": function(body) { - var span = body.selectAll("span"); - assert.equal(span.length, 1); - assert.equal(span[0].length, 0); - }, - "can select via function": function(body) { - var d = {}, dd = [], ii = [], tt = [], - s = body.data([d]).selectAll(function(d, i) { dd.push(d); ii.push(i); tt.push(this); return this.childNodes; }); - assert.deepEqual(dd, [d], "expected data, got {actual}"); - assert.deepEqual(ii, [0], "expected index, got {actual}"); - assert.domEqual(tt[0], body.node(), "expected this, got {actual}"); - assert.domEqual(s[0][0], body.node().firstChild); - assert.domEqual(s[0][1], body.node().lastChild); - delete body.node().__data__; - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/selection").document(), - "on a simple page": { - topic: function(d3) { - var div = d3.select("body").append("div").selectAll("div").data([0, 1]).enter().append("div"); - div.append("span").attr("class", "first"); - div.append("span").attr("class", "second"); - return div; - }, - "selects all matching elements": function(div) { - var span = div.selectAll("span"); - assert.equal(span.length, 2); - assert.equal(span[0].length, 2); - assert.isTrue(span[0][0].parentNode === div[0][0]); - assert.isTrue(span[0][1].parentNode === div[0][0]); - assert.isTrue(span[1][0].parentNode === div[0][1]); - assert.isTrue(span[1][1].parentNode === div[0][1]); - }, - "propagates parent node to the selected elements": function(div) { - var span = div.selectAll("span"); - assert.isNotNull(span[0].parentNode); - assert.isTrue(span[0].parentNode === div[0][0]); - assert.isTrue(span[1].parentNode === div[0][1]); - }, - "does not propagate data if data was specified": function(div) { - var span = div.selectAll("span"); - delete span[0][0].__data__; - delete span[0][1].__data__; - span = div.data([new Object(), new Object()]).selectAll("span"); - assert.isUndefined(span[0][0].__data__); - assert.isUndefined(span[0][1].__data__); - }, - "does not propagate data if data was not specified": function(div) { - var a = new Object(), b = new Object(), span = div.selectAll("span").data([a, b]); - delete div[0][0].__data__; - delete div[0][1].__data__; - span = div.selectAll("span"); - assert.equal(span[0][0].__data__, a); - assert.equal(span[0][1].__data__, b); - }, - "returns empty array if no match is found": function(div) { - var div = div.selectAll("div"); - assert.equal(div.length, 2); - assert.equal(div[0].length, 0); - assert.equal(div[1].length, 0); - }, - "can select via function": function(div) { - var dd = [], ii = [], tt = [], - s = div.data(["a", "b"]).selectAll(function(d, i) { dd.push(d); ii.push(i); tt.push(this); return this.childNodes; }); - assert.deepEqual(dd, ["a", "b"], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.domEqual(tt[0], div[0][0], "expected this, got {actual}"); - assert.domEqual(tt[1], div[0][1], "expected this, got {actual}"); - assert.domEqual(s[0][0], div[0][0].firstChild); - assert.domEqual(s[0][1], div[0][0].lastChild); - assert.domEqual(s[1][0], div[0][1].firstChild); - assert.domEqual(s[1][1], div[0][1].lastChild); - }, - "ignores null nodes": function(div) { - var node = div[0][1]; - div[0][1] = null; - var span = div.selectAll("span"); - assert.equal(span.length, 1); - assert.equal(span[0].length, 2); - assert.isTrue(span[0][0].parentNode === div[0][0]); - assert.isTrue(span[0][1].parentNode === div[0][0]); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/selection-test.js b/test/selection/selection-test.js deleted file mode 100644 index 313ad4aa75c2a2..00000000000000 --- a/test/selection/selection-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.selection"); - -suite.addBatch({ - "selection": { - topic: load("selection/selection").document(), - "selects the document element": function(d3) { - var selection = d3.selection(); - assert.equal(selection.length, 1); - assert.equal(selection[0].length, 1); - assert.equal(selection[0][0].nodeType, 1); - assert.equal(selection[0][0].tagName, "HTML"); - }, - "the parentNode is also the document element": function(d3) { - var parentNode = d3.selection()[0].parentNode; - assert.equal(parentNode.nodeType, 1); - assert.equal(parentNode.tagName, "HTML"); - }, - "is an instanceof d3.selection": function(d3) { - assert.instanceOf(d3.selection(), d3.selection); - }, - "subselections are also instanceof d3.selection": function(d3) { - assert.instanceOf(d3.selection().select("body"), d3.selection); - assert.instanceOf(d3.selection().selectAll("body"), d3.selection); - }, - "selection prototype can be extended": function(d3) { - d3.selection.prototype.foo = function(v) { return this.attr("foo", v); }; - var body = d3.selection().select("body").foo(42); - assert.equal(body.attr("foo"), "42"); - delete d3.selection.prototype.foo; - } - } -}); - -suite.export(module); diff --git a/test/selection/size-test.js b/test/selection/size-test.js deleted file mode 100644 index f9c86cb7a44f87..00000000000000 --- a/test/selection/size-test.js +++ /dev/null @@ -1,52 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.size"); - -suite.addBatch({ - "select(body)": { - topic: load("selection/size").document(), - "on a simple page": { - topic: function(d3) { - return d3.select("body"); - }, - "returns zero for empty selections": function(body) { - assert.equal(body.select("foo").size(), 0); - }, - "returns one for a singleton selection": function(body) { - assert.equal(body.size(), 1); - }, - "does not count null nodes": function(body) { - body[0][0] = null; - assert.equal(body.size(), 0); - } - } - } -}); - -suite.addBatch({ - "selectAll(div)": { - topic: load("selection/size").document(), - "on a simple page": { - topic: function(d3) { - var body = d3.select("body"); - body.append("div").append("span"); - body.append("div"); - return body.selectAll("div"); - }, - "returns null for empty selections": function(div) { - assert.equal(div.select("foo").size(), 0); - }, - "returns the number of non-null nodes": function(div) { - assert.equal(div.size(), 2); - }, - "does not count null nodes": function(div) { - div[0][0] = null; - assert.equal(div.size(), 1); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/sort-test.js b/test/selection/sort-test.js deleted file mode 100644 index 73c7d9ba2c2abd..00000000000000 --- a/test/selection/sort-test.js +++ /dev/null @@ -1,81 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.sort"); - -suite.addBatch({ - "selectAll(div).selectAll(span)": { - topic: load("selection/sort").document(), - "on a page with some spans": { - topic: function(d3) { - return d3.select("body").append("div").selectAll("div") - .data([1, 2, 10, 20]) - .enter().append("div") - .selectAll("span") - .data(function(d) { return [20 + d, 2 + d, 10, 1]; }) - .enter().append("span"); - }, - "sorts elements by natural order": function(span) { - span.sort(); - assert.domNull(span[0][0].previousSibling); - assert.domEqual(span[0][1].previousSibling, span[0][0]); - assert.domEqual(span[0][2].previousSibling, span[0][1]); - assert.domEqual(span[0][3].previousSibling, span[0][2]); - assert.domNull(span[0][3].nextSibling); - }, - "sorts each group independently": function(span) { - span.sort(function(a, b) { return b - a; }); - assert.deepEqual(span[0].map(data), [21, 10, 3, 1]); - assert.deepEqual(span[1].map(data), [22, 10, 4, 1]); - assert.deepEqual(span[2].map(data), [30, 12, 10, 1]); - assert.deepEqual(span[3].map(data), [40, 22, 10, 1]); - }, - "sorts using the specified comparator": function(span) { - span.sort(function(a, b) { return (a + "").localeCompare(b + ""); }); - assert.deepEqual(span[0].map(data), [1, 10, 21, 3]); - assert.deepEqual(span[1].map(data), [1, 10, 22, 4]); - assert.deepEqual(span[2].map(data), [1, 10, 12, 30]); - assert.deepEqual(span[3].map(data), [1, 10, 22, 40]); - }, - "returns the current selection": function(span) { - assert.isTrue(span.sort() === span); - }, - "sorts null nodes at the end of the selection": function(span) { - var nulls = 0; - span[0][0].parentNode.removeChild(span[0][0]); - span[0][2].parentNode.removeChild(span[0][2]); - span[0][0] = span[0][2] = null; - span.sort(function(a, b) { if ((a === null) || (b === null)) ++nulls; return a - b; }); - assert.equal(nulls, 0); - - assert.domNull(span[0][2]); - assert.domNull(span[0][3]); - assert.domNull(span[0][0].previousSibling); - assert.domEqual(span[0][1], span[0][0].nextSibling); - assert.domEqual(span[0][0], span[0][1].previousSibling); - assert.domNull(span[0][1].nextSibling); - assert.deepEqual(span[0].slice(0, -2).map(data), [3, 21]); - - for (var i = 1; i < 4; ++i) { - var d = span[i].parentNode.__data__; - assert.domNull(span[i][0].previousSibling); - assert.domEqual(span[i][1], span[i][0].nextSibling); - assert.domEqual(span[i][0], span[i][1].previousSibling); - assert.domEqual(span[i][2], span[i][1].nextSibling); - assert.domEqual(span[i][1], span[i][2].previousSibling); - assert.domEqual(span[i][3], span[i][2].nextSibling); - assert.domEqual(span[i][2], span[i][3].previousSibling); - assert.domNull(span[i][3].nextSibling); - assert.deepEqual(span[i].map(data), [1, 2 + d, 10, 20 + d].sort(function(a, b) { return a - b; })); - } - } - } - } -}); - -function data(d) { - return d.__data__; -} - -suite.export(module); diff --git a/test/selection/style-test.js b/test/selection/style-test.js deleted file mode 100644 index bdadc78b737e44..00000000000000 --- a/test/selection/style-test.js +++ /dev/null @@ -1,129 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.style"); - -suite.addBatch({ - "on select(body)": { - topic: load("selection/style").document(), - "on an initially-empty page": { - topic: function(d3) { - return d3.select("body"); - }, - "sets a property as a string": function(body) { - body.style("background-color", "red"); - assert.equal(body.node().style.getPropertyValue("background-color"), "red"); - }, - "sets a property as a number": function(body) { - body.style("opacity", .3); - assert.equal(body.node().style.getPropertyValue("opacity"), "0.3"); - }, - "sets a property as a function": function(body) { - body.style("background-color", function() { return "orange"; }); - assert.equal(body.node().style.getPropertyValue("background-color"), "orange"); - }, - "sets properties as a map of constants": function(body) { - body.style({"background-color": "white", opacity: .42}); - assert.equal(body.node().style.getPropertyValue("background-color"), "white"); - assert.equal(body.node().style.getPropertyValue("opacity"), "0.42"); - }, - "sets properties as a map of functions": function(body) { - body.data(["orange"]).style({"background-color": String, opacity: function(d, i) { return i; }}); - assert.equal(body.node().style.getPropertyValue("background-color"), "orange"); - assert.equal(body.node().style.getPropertyValue("opacity"), "0"); - }, - "gets a property value": function(body) { - body.node().style.setProperty("background-color", "yellow", ""); - assert.equal(body.style("background-color"), "yellow"); - }, - "observes the specified priority": function(body) { - body.style("background-color", "green", "important"); - assert.equal(body.node().style.getPropertyPriority("background-color"), "important"); - body.style({opacity: .52}, "important"); - assert.equal(body.node().style.getPropertyPriority("opacity"), "important"); - body.style({visibility: function() { return "visible"; }}, "important"); - assert.equal(body.node().style.getPropertyPriority("visibility"), "important"); - }, - "removes a property as null": function(body) { - body.style("background-color", "green").style("background-color", null); - assert.equal(body.style("background-color"), ""); - }, - "removes a property as a function": function(body) { - body.style("background-color", "green").style("background-color", function() { return null; }); - assert.equal(body.style("background-color"), ""); - }, - "removes properties as a map of nulls": function(body) { - body.node().style.setProperty("background-color", "purple"); - body.style({"background-color": null}); - assert.equal(body.style("background-color"), ""); - }, - "removes properties as a map of functions that return null": function(body) { - body.node().style.setProperty("background-color", "purple"); - body.style({"background-color": function() {}}); - assert.equal(body.style("background-color"), ""); - }, - "returns the current selection": function(body) { - assert.isTrue(body.style("background-color", "green") === body); - } - } - } -}); - -suite.addBatch({ - "on selectAll(div)": { - topic: load("selection/style").document(), - "on a page with a few divs": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "sets a property as a string": function(div) { - div.style("background-color", "red"); - assert.equal(div[0][0].style.getPropertyValue("background-color"), "red"); - assert.equal(div[0][1].style.getPropertyValue("background-color"), "red"); - }, - "sets a property as a number": function(div) { - div.style("opacity", .5); - assert.equal(div[0][0].style.getPropertyValue("opacity"), "0.5"); - assert.equal(div[0][1].style.getPropertyValue("opacity"), "0.5"); - }, - "sets a property as a function": function(div) { - div.style("background-color", _.interpolateRgb("orange", "yellow")); - assert.equal(div[0][0].style.getPropertyValue("background-color"), "#ffa500"); - assert.equal(div[0][1].style.getPropertyValue("background-color"), "#ffff00"); - }, - "gets a property value": function(div) { - div[0][0].style.setProperty("background-color", "green", ""); - assert.equal(div.style("background-color"), "green"); - }, - "observes the specified priority": function(div) { - div.style("background-color", "blue", "important"); - assert.equal(div[0][0].style.getPropertyPriority("background-color"), "important"); - assert.equal(div[0][1].style.getPropertyPriority("background-color"), "important"); - }, - "removes a property as null": function(div) { - div.style("background-color", "red").style("background-color", null); - assert.equal(div[0][0].style.getPropertyValue("background-color"), ""); - assert.equal(div[0][1].style.getPropertyValue("background-color"), ""); - }, - "removes a property as a function": function(div) { - div.style("background-color", "red").style("background-color", function() { return null; }); - assert.equal(div[0][0].style.getPropertyValue("background-color"), ""); - assert.equal(div[0][1].style.getPropertyValue("background-color"), ""); - }, - "returns the current selection": function(div) { - assert.isTrue(div.style("background-color", "green") === div); - }, - "ignores null nodes": function(div) { - var node = div[0][1]; - div[0][1] = null; - div.style("background-color", null).style("background-color", "red"); - assert.equal(div[0][0].style.getPropertyValue("background-color"), "red"); - assert.equal(node.style.getPropertyValue("background-color"), "green"); - } - } - } -}); - -suite.export(module); diff --git a/test/selection/text-test.js b/test/selection/text-test.js deleted file mode 100644 index 13f994a86d45f9..00000000000000 --- a/test/selection/text-test.js +++ /dev/null @@ -1,115 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("selection.text"); - -suite.addBatch({ - "on select(body)": { - topic: load("selection/text").document(), - "on an initially-empty page": { - topic: function(d3) { - return d3.select("body"); - }, - "sets the text content as a string": function(body) { - body.text("Hello, world!"); - assert.equal(body.node().textContent, "Hello, world!"); - }, - "sets the text content as a number": function(body) { - body.text(42); - assert.equal(body.node().textContent, "42"); - }, - "sets the text content as a function": function(body) { - body.data(["Subject"]).text(function(d, i) { return "Hello, " + d + " " + i + "!"; }); - assert.equal(body.node().textContent, "Hello, Subject 0!"); - }, - "escapes html content to text": function(body) { - body.text("

Hello, world!

"); - assert.equal(body.node().textContent, "

Hello, world!

"); - assert.equal(body.node().firstChild.nodeType, 3); - }, - "clears the text content as null": function(body) { - body.text(null); - assert.equal(body.node().textContent, ""); - }, - "clears the text content as undefined": function(body) { - body.text(undefined); - assert.equal(body.node().textContent, ""); - }, - "clears the text content as a function returning null": function(body) { - body.text(function() { return null; }); - assert.equal(body.node().textContent, ""); - }, - "clears the text content as a function returning undefined": function(body) { - body.text(function() { return undefined; }); - assert.equal(body.node().textContent, ""); - }, - "returns the current selection": function(body) { - assert.isTrue(body.text("hello") === body); - }, - "ignores null nodes": function(body) { - var node = body.node(); - node.textContent = "foo"; - body[0][0] = null; - body.text("bar"); - assert.equal(node.textContent, "foo"); - } - } - } -}); - -suite.addBatch({ - "on selectAll(div)": { - topic: load("selection/text").document(), - "on a page with a few divs": { - topic: function(d3) { - return d3.select("body").selectAll("div").data([0, 1]).enter().append("div"); - }, - "sets the text content as a string": function(div) { - div.text("Hello, world!"); - assert.equal(div[0][0].textContent, "Hello, world!"); - assert.equal(div[0][1].textContent, "Hello, world!"); - }, - "sets the text content as a number": function(div) { - div.text(42); - assert.equal(div[0][0].textContent, "42"); - assert.equal(div[0][1].textContent, "42"); - }, - "sets the text content as a function": function(div) { - div.data(["foo", "bar"]).text(function(d, i) { return "Hello, " + d + " " + i + "!"; }); - assert.equal(div[0][0].textContent, "Hello, foo 0!"); - assert.equal(div[0][1].textContent, "Hello, bar 1!"); - }, - "escapes html content to text": function(div) { - div.text("

Hello, world!

"); - assert.equal(div[0][0].textContent, "

Hello, world!

"); - assert.equal(div[0][1].textContent, "

Hello, world!

"); - assert.equal(div[0][0].firstChild.nodeType, 3); - assert.equal(div[0][1].firstChild.nodeType, 3); - }, - "clears the text content as null": function(div) { - div.text(null); - assert.equal(div[0][0].textContent, ""); - assert.equal(div[0][1].textContent, ""); - }, - "clears the text content as a function": function(div) { - div.text(function() { return null; }); - assert.equal(div[0][0].textContent, ""); - assert.equal(div[0][1].textContent, ""); - }, - "returns the current selection": function(div) { - assert.isTrue(div.text("hello") === div); - }, - "ignores null nodes": function(div) { - var node = div[0][0]; - node.textContent = "foo"; - div[0][0] = null; - div.text("bar"); - assert.equal(node.textContent, "foo"); - assert.equal(div[0][1].textContent, "bar"); - } - } - } -}); - -suite.export(module); diff --git a/test/svg/arc-test.js b/test/svg/arc-test.js deleted file mode 100644 index 393856e1414e13..00000000000000 --- a/test/svg/arc-test.js +++ /dev/null @@ -1,143 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.arc"); - -suite.addBatch({ - "arc": { - topic: load("svg/arc").expression("d3.svg.arc"), - - "innerRadius defaults to a function accessor": function(arc) { - var a = arc().outerRadius(100).startAngle(0).endAngle(Math.PI); - assert.pathEqual(a({innerRadius: 0}), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - assert.pathEqual(a({innerRadius: 50}), "M0,-100A100,100 0 1,1 0,100L0,50A50,50 0 1,0 0,-50Z"); - }, - "innerRadius can be defined as a constant": function(arc) { - var a = arc().outerRadius(100).startAngle(0).endAngle(Math.PI); - assert.pathEqual(a.innerRadius(0)(), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - assert.pathEqual(a.innerRadius(50)(), "M0,-100A100,100 0 1,1 0,100L0,50A50,50 0 1,0 0,-50Z"); - }, - "innerRadius can be defined as a function of data or index": function(arc) { - var a = arc().innerRadius(f).outerRadius(100).startAngle(0).endAngle(Math.PI), o = {}, t = {}, dd, ii, tt; - function f(d, i) { dd = d; ii = i; tt = this; return 42; } - assert.pathEqual(a.call(t, o, 2), "M0,-100A100,100 0 1,1 0,100L0,42A42,42 0 1,0 0,-42Z"); - assert.equal(dd, o, "expected data, got {actual}"); - assert.equal(ii, 2, "expected index, got {actual}"); - assert.equal(tt, t, "expected this, got {actual}"); - }, - - "outerRadius defaults to a function accessor": function(arc) { - var a = arc().innerRadius(0).startAngle(0).endAngle(Math.PI); - assert.pathEqual(a({outerRadius: 50}), "M0,-50A50,50 0 1,1 0,50L0,0Z"); - assert.pathEqual(a({outerRadius: 100}), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - }, - "outerRadius can be defined as a constant": function(arc) { - var a = arc().innerRadius(0).startAngle(0).endAngle(Math.PI); - assert.pathEqual(a.outerRadius(50)(), "M0,-50A50,50 0 1,1 0,50L0,0Z"); - assert.pathEqual(a.outerRadius(100)(), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - }, - "outerRadius can be defined as a function of data or index": function(arc) { - var a = arc().innerRadius(0).outerRadius(f).startAngle(0).endAngle(Math.PI), o = {}, t = {}, dd, ii, tt; - function f(d, i) { dd = d; ii = i; tt = this; return 42; } - assert.pathEqual(a.call(t, o, 2), "M0,-42A42,42 0 1,1 0,42L0,0Z"); - assert.equal(dd, o, "expected data, got {actual}"); - assert.equal(ii, 2, "expected index, got {actual}"); - assert.equal(tt, t, "expected this, got {actual}"); - }, - - "startAngle defaults to a function accessor": function(arc) { - var a = arc().innerRadius(0).outerRadius(100).endAngle(Math.PI); - assert.pathEqual(a({startAngle: 0}), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - assert.pathEqual(a({startAngle: Math.PI / 2}), "M100,0A100,100 0 0,1 0,100L0,0Z"); - }, - "startAngle can be defined as a constant": function(arc) { - var a = arc().innerRadius(0).outerRadius(100).endAngle(Math.PI); - assert.pathEqual(a.startAngle(0)(), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - assert.pathEqual(a.startAngle(Math.PI / 2)(), "M100,0A100,100 0 0,1 0,100L0,0Z"); - }, - "startAngle can be defined as a function of data or index": function(arc) { - var a = arc().innerRadius(0).outerRadius(100).startAngle(f).endAngle(Math.PI), o = {}, t = {}, dd, ii, tt; - function f(d, i) { dd = d; ii = i; tt = this; return Math.PI; } - assert.pathEqual(a.call(t, o, 2), "M0,100A100,100 0 0,1 0,100L0,0Z"); - assert.equal(dd, o, "expected data, got {actual}"); - assert.equal(ii, 2, "expected index, got {actual}"); - assert.equal(tt, t, "expected this, got {actual}"); - }, - - "endAngle defaults to a function accessor": function(arc) { - var a = arc().innerRadius(0).outerRadius(100).startAngle(0); - assert.pathEqual(a({endAngle: Math.PI / 2}), "M0,-100A100,100 0 0,1 100,0L0,0Z"); - assert.pathEqual(a({endAngle: Math.PI}), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - }, - "endAngle can be defined as a constant": function(arc) { - var a = arc().innerRadius(0).outerRadius(100).startAngle(0); - assert.pathEqual(a.endAngle(Math.PI / 2)(), "M0,-100A100,100 0 0,1 100,0L0,0Z"); - assert.pathEqual(a.endAngle(Math.PI)(), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - }, - "endAngle can be defined as a function of data or index": function(arc) { - var a = arc().innerRadius(0).outerRadius(100).startAngle(0).endAngle(f), o = {}, t = {}, dd, ii, tt; - function f(d, i) { dd = d; ii = i; tt = this; return Math.PI; } - assert.pathEqual(a.call(t, o, 2), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - assert.equal(dd, o, "expected data, got {actual}"); - assert.equal(ii, 2, "expected index, got {actual}"); - assert.equal(tt, t, "expected this, got {actual}"); - }, - - "startAngle and endAngle are swapped if endAngle is less than startAngle": function(arc) { - var a = arc().innerRadius(50).outerRadius(100); - assert.pathEqual(a.startAngle(2 * Math.PI).endAngle(Math.PI)(), a.startAngle(Math.PI).endAngle(2 * Math.PI)()); - assert.pathEqual(a.startAngle(-Math.PI).endAngle(Math.PI)(), a.startAngle(Math.PI).endAngle(-Math.PI)()); - }, - - "angles are defined in radians, with zero at 12 o'clock": function(arc) { - var a = arc().innerRadius(0).outerRadius(100); - assert.pathEqual(a.startAngle(0).endAngle(Math.PI)(), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - assert.pathEqual(a.startAngle(Math.PI).endAngle(2 * Math.PI)(), "M0,100A100,100 0 1,1 0,-100L0,0Z"); - }, - "radii are defined in local coordinates (typically pixels)": function(arc) { - var a = arc().startAngle(0).endAngle(Math.PI); - assert.pathEqual(a.innerRadius(0).outerRadius(100)(), "M0,-100A100,100 0 1,1 0,100L0,0Z"); - assert.pathEqual(a.innerRadius(100).outerRadius(200)(), "M0,-200A200,200 0 1,1 0,200L0,100A100,100 0 1,0 0,-100Z"); - }, - "draws a circle when inner radius is zero and angle is approximately 2π": function(arc) { - var a = arc().innerRadius(0).outerRadius(100); - assert.pathEqual(a.startAngle(0).endAngle(2 * Math.PI - 1e-9)(), "M0,100A100,100 0 1,1 0,-100A100,100 0 1,1 0,100Z"); - assert.pathEqual(a.startAngle(Math.PI + 1e-9).endAngle(3 * Math.PI - 1e-9)(), "M0,100A100,100 0 1,1 0,-100A100,100 0 1,1 0,100Z"); - }, - "draws a circle when inner radius is zero and angle is greater than 2π": function(arc) { - var a = arc().innerRadius(0).outerRadius(100); - assert.pathEqual(a.startAngle(0).endAngle(7)(), "M0,100A100,100 0 1,1 0,-100A100,100 0 1,1 0,100Z"); - assert.pathEqual(a.startAngle(1).endAngle(8)(), "M0,100A100,100 0 1,1 0,-100A100,100 0 1,1 0,100Z"); - }, - "draws a circular sector when inner radius is zero and angle is less than 2π": function(arc) { - var a = arc().innerRadius(0).outerRadius(100); - assert.pathEqual(a.startAngle(0).endAngle(Math.PI / 2)(), "M0,-100A100,100 0 0,1 100,0L0,0Z"); - }, - "draws an annulus when inner radius is non-zero and angle is approximately 2π": function(arc) { - var a = arc().innerRadius(100).outerRadius(200); - assert.pathEqual(a.startAngle(0).endAngle(2 * Math.PI - 1e-9)(), "M0,200A200,200 0 1,1 0,-200A200,200 0 1,1 0,200M0,100A100,100 0 1,0 0,-100A100,100 0 1,0 0,100Z"); - assert.pathEqual(a.startAngle(Math.PI + 1e-9).endAngle(3 * Math.PI - 1e-9)(), "M0,200A200,200 0 1,1 0,-200A200,200 0 1,1 0,200M0,100A100,100 0 1,0 0,-100A100,100 0 1,0 0,100Z"); - }, - "draws an annulus when inner radius is non-zero and angle is greater than 2π": function(arc) { - var a = arc().innerRadius(100).outerRadius(200); - assert.pathEqual(a.startAngle(0).endAngle(7)(), "M0,200A200,200 0 1,1 0,-200A200,200 0 1,1 0,200M0,100A100,100 0 1,0 0,-100A100,100 0 1,0 0,100Z"); - assert.pathEqual(a.startAngle(-1).endAngle(6)(), "M0,200A200,200 0 1,1 0,-200A200,200 0 1,1 0,200M0,100A100,100 0 1,0 0,-100A100,100 0 1,0 0,100Z"); - }, - "draws an annular sector when both radii are non-zero and angle is less than 2π": function(arc) { - var a = arc().innerRadius(100).outerRadius(200); - assert.pathEqual(a.startAngle(0).endAngle(Math.PI / 2)(), "M0,-200A200,200 0 0,1 200,0L100,0A100,100 0 0,0 0,-100Z"); - }, - - "computes the centroid as mid-radius and mid-angle": function(arc) { - var c = arc().innerRadius(0).outerRadius(100).startAngle(0).endAngle(2 * Math.PI).centroid(); - assert.inDelta(c[0], 0, 1e-6); - assert.inDelta(c[1], 50, 1e-6); - var c = arc().innerRadius(100).outerRadius(200).startAngle(Math.PI).endAngle(2 * Math.PI).centroid(); - assert.inDelta(c[0], -150, 1e-6); - assert.inDelta(c[1], 0, 1e-6); - } - } -}); - -suite.export(module); diff --git a/test/svg/area-radial-test.js b/test/svg/area-radial-test.js deleted file mode 100644 index d837217b1fcf3a..00000000000000 --- a/test/svg/area-radial-test.js +++ /dev/null @@ -1,199 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.area.radial"); - -suite.addBatch({ - "area.radial": { - topic: load("svg/area-radial").expression("d3.svg.area.radial"), - - "radius is an alias for setting innerRadius and outerRadius": function(area) { - var a = area().radius(f); - function f() {} - assert.equal(a.radius(), f); - assert.equal(a.innerRadius(), f); - assert.equal(a.outerRadius(), f); - }, - "radius is an alias for getting outerRadius": function(area) { - var a = area().outerRadius(f); - function f() {} - assert.equal(a.radius(), f); - }, - - "angle is an alias for setting startAngle and endAngle": function(area) { - var a = area().angle(f); - function f() {} - assert.equal(a.angle(), f); - assert.equal(a.startAngle(), f); - assert.equal(a.endAngle(), f); - }, - "angle is an alias for getting endAngle": function(area) { - var a = area().endAngle(f); - function f() {} - assert.equal(a.angle(), f); - }, - - "innerRadius defaults to a function accessor": function(area) { - var a = area(); - assert.pathEqual(a([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.829420,-10.806046L18.185949,8.322937L1.411200,9.899925L0,-10L0,-20L0,-20L0,-10Z"); - assert.typeOf(a.innerRadius(), "function"); - }, - "innerRadius can be defined as a constant": function(area) { - var a = area().innerRadius(30); - assert.pathEqual(a([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.829420,-10.806046L18.185949,8.322937L1.411200,9.899925L0,-30L0,-30L0,-30L0,-30Z"); - assert.equal(a.innerRadius(), 30); - }, - "innerRadius can be defined as a function": function(area) { - var a = area().innerRadius(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 30; } - assert.pathEqual(a.call(t, [[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.829420,-10.806046L18.185949,8.322937L1.411200,9.899925L0,-30L0,-30L0,-30L0,-30Z"); - assert.deepEqual(dd, [[10, 0], [20, 1], [20, 2], [10, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1, 2, 3], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t, t, t], "expected this, got {actual}"); - }, - - "outerRadius defaults to a function accessor": function(area) { - var a = area(); - assert.pathEqual(a([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.829420,-10.806046L18.185949,8.322937L1.411200,9.899925L0,-10L0,-20L0,-20L0,-10Z"); - assert.typeOf(a.outerRadius(), "function"); - }, - "outerRadius can be defined as a constant": function(area) { - var a = area().outerRadius(30); - assert.pathEqual(a([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-30L25.244130,-16.209069L27.278923,12.484405L4.233600,29.699775L0,-10L0,-20L0,-20L0,-10Z"); - assert.equal(a.outerRadius(), 30); - }, - "outerRadius can be defined as a function": function(area) { - var a = area().outerRadius(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 30; } - assert.pathEqual(a.call(t, [[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-30L25.244130,-16.209069L27.278923,12.484405L4.233600,29.699775L0,-10L0,-20L0,-20L0,-10Z"); - assert.deepEqual(dd, [[10, 0], [20, 1], [20, 2], [10, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1, 2, 3], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t, t, t], "expected this, got {actual}"); - }, - - "startAngle defaults to zero": function(area) { - var a = area(); - assert.pathEqual(a([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.829420,-10.806046L18.185949,8.322937L1.411200,9.899925L0,-10L0,-20L0,-20L0,-10Z"); - assert.equal(a.startAngle(), 0); - }, - "startAngle can be defined as a constant": function(area) { - var a = area().startAngle(Math.PI / 2); - assert.pathEqual(a([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.829420,-10.806046L18.185949,8.322937L1.411200,9.899925L10,0L20,0L20,0L10,0Z"); - assert.equal(a.startAngle(), Math.PI / 2); - }, - "startAngle can be defined as a function": function(area) { - var a = area().startAngle(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return Math.PI / 2; } - assert.pathEqual(a.call(t, [[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.829420,-10.806046L18.185949,8.322937L1.411200,9.899925L10,0L20,0L20,0L10,0Z"); - assert.deepEqual(dd, [[10, 0], [20, 1], [20, 2], [10, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1, 2, 3], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t, t, t], "expected this, got {actual}"); - }, - - "endAngle defaults to a function accessor": function(area) { - var a = area(); - assert.pathEqual(a([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.829420,-10.806046L18.185949,8.322937L1.411200,9.899925L0,-10L0,-20L0,-20L0,-10Z"); - assert.typeOf(a.endAngle(), "function"); - }, - "endAngle can be defined as a constant": function(area) { - var a = area().endAngle(Math.PI / 2); - assert.pathEqual(a([[10, 0], [20, 1], [20, 2], [10, 3]]), "M10,0L20,0L20,0L10,0L0,-10L0,-20L0,-20L0,-10Z"); - assert.equal(a.endAngle(), Math.PI / 2); - }, - "endAngle can be defined as a function": function(area) { - var a = area().endAngle(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return Math.PI / 2; } - assert.pathEqual(a.call(t, [[10, 0], [20, 1], [20, 2], [10, 3]]), "M10,0L20,0L20,0L10,0L0,-10L0,-20L0,-20L0,-10Z"); - assert.deepEqual(dd, [[10, 0], [20, 1], [20, 2], [10, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1, 2, 3], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t, t, t], "expected this, got {actual}"); - }, - - "if innerRadius === outerRadius, radius is only evaluated once per point": function(area) { - var a = area().radius(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 30; } - assert.pathEqual(a.call(t, [[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-30L25.244130,-16.209069L27.278923,12.484405L4.233600,29.699775L0,-30L0,-30L0,-30L0,-30Z"); - assert.deepEqual(dd, [[10, 0], [20, 1], [20, 2], [10, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1, 2, 3], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t, t, t], "expected this, got {actual}"); - }, - "if startAngle === endAngle, angle is only evaluated once per point": function(area) { - var a = area().angle(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return Math.PI / 2; } - assert.pathEqual(a.call(t, [[10, 0], [20, 1], [20, 2], [10, 3]]), "M10,0L20,0L20,0L10,0L10,0L20,0L20,0L10,0Z"); - assert.deepEqual(dd, [[10, 0], [20, 1], [20, 2], [10, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1, 2, 3], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t, t, t], "expected this, got {actual}"); - }, - - "interpolate defaults to linear": function(area) { - assert.equal(area().interpolate(), "linear"); - }, - "interpolate can be defined as a constant": function(area) { - var a = area().interpolate("step-before"); - assert.pathEqual(a([[0, 0], [1, 1]]), "M0,0V-0.540302H0.841471L0,-1H0V0Z"); - assert.equal(a.interpolate(), "step-before"); - }, - - "tension defaults to .7": function(area) { - assert.equal(area().tension(), .7); - }, - "tension can be specified as a constant": function(area) { - var a = area().tension(.5); - assert.equal(a.tension(), .5); - }, - - "returns null if input points array is empty": function(area) { - assert.isNull(area()([])); - }, - - "interpolate(linear)": { - "supports linear interpolation": testInterpolation("linear") - }, - - "interpolate(step)": { - "supports step-before interpolation": testInterpolation("step-before"), - "supports step-after interpolation": testInterpolation("step-after") - }, - - "interpolate(basis)": { - "supports basis interpolation": testInterpolation("basis"), - "supports basis-open interpolation": testInterpolation("basis-open"), - "supports basis-closed interpolation": testInterpolation("basis-closed") - }, - - "interpolate(cardinal)": { - "supports cardinal interpolation": testInterpolation("cardinal"), - "supports cardinal-open interpolation": testInterpolation("cardinal-open"), - "supports cardinal-closed interpolation": testInterpolation("cardinal-closed") - }, - - "interpolate(monotone)": { - "supports monotone interpolation": testInterpolation("monotone") - } - } -}); - -// A radial area is just a transformation of a Cartesian line. -function testInterpolation(interpolate) { - var data = [[10, 0], [20, 1], [20, 2], [10, 3]]; - - var cartesian = _.svg.area() - .x0(function(d) { return d[0] * Math.cos(d[1] - Math.PI / 2); }) - .x1(function(d) { return 2 * d[0] * Math.cos(d[1] - Math.PI / 2); }) - .y0(function(d) { return d[0] * Math.sin(d[1] - Math.PI / 2); }) - .y1(function(d) { return 2 * d[0] * Math.sin(d[1] - Math.PI / 2); }); - - return function(area) { - var radial = area() - .innerRadius(function(d) { return d[0]; }) - .outerRadius(function(d) { return d[0] * 2; }) - .angle(function(d) { return d[1]; }); - - assert.pathEqual(radial.interpolate(interpolate)(data), cartesian.interpolate(interpolate)(data)); - }; -} - -suite.export(module); diff --git a/test/svg/area-test.js b/test/svg/area-test.js deleted file mode 100644 index 289815c3a73ea1..00000000000000 --- a/test/svg/area-test.js +++ /dev/null @@ -1,192 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.area"); - -suite.addBatch({ - "area": { - topic: load("svg/area").expression("d3.svg.area"), - - "x is an alias for setting x0 and x1": function(area) { - var a = area().x(f); - function f() {} - assert.equal(a.x(), f); - assert.equal(a.x0(), f); - assert.equal(a.x1(), f); - }, - "x is an alias for getting x1": function(area) { - var a = area().x1(f); - function f() {} - assert.equal(a.x(), f); - }, - - "y is an alias for setting y0 and y1": function(area) { - var a = area().y(f); - function f() {} - assert.equal(a.y(), f); - assert.equal(a.y0(), f); - assert.equal(a.y1(), f); - }, - "y is an alias for getting x1": function(area) { - var a = area().y1(f); - function f() {} - assert.equal(a.y(), f); - }, - - "x0 defaults to a function accessor": function(area) { - var a = area(); - assert.pathEqual(a([[1, 2], [4, 3]]), "M1,2L4,3L4,0L1,0Z"); - assert.typeOf(a.x0(), "function"); - }, - "x0 can be defined as a constant": function(area) { - var a = area().x0(0); - assert.pathEqual(a([[1, 2], [4, 3]]), "M1,2L4,3L0,0L0,0Z"); - assert.equal(a.x0(), 0); - }, - "x0 can be defined as a function": function(area) { - var a = area().x0(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 0; } - assert.pathEqual(a.call(t, [[1, 2], [4, 3]]), "M1,2L4,3L0,0L0,0Z"); - assert.deepEqual(dd, [[1, 2], [4, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t], "expected this, got {actual}"); - }, - - "x1 defaults to a function accessor": function(area) { - var a = area(); - assert.pathEqual(a([[1, 2], [4, 3]]), "M1,2L4,3L4,0L1,0Z"); - assert.typeOf(a.x1(), "function"); - }, - "x1 can be defined as a constant": function(area) { - var a = area().x1(0); - assert.pathEqual(a([[1, 2], [4, 3]]), "M0,2L0,3L4,0L1,0Z"); - assert.equal(a.x1(), 0); - }, - "x1 can be defined as a function": function(area) { - var a = area().x1(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 0; } - assert.pathEqual(a.call(t, [[1, 2], [4, 3]]), "M0,2L0,3L4,0L1,0Z"); - assert.deepEqual(dd, [[1, 2], [4, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t], "expected this, got {actual}"); - }, - - "y0 defaults to zero": function(area) { - var a = area(); - assert.pathEqual(a([[1, 2], [4, 3]]), "M1,2L4,3L4,0L1,0Z"); - assert.equal(a.y0(), 0); - }, - "y0 can be defined as a constant": function(area) { - var a = area().y0(1); - assert.pathEqual(a([[1, 2], [4, 3]]), "M1,2L4,3L4,1L1,1Z"); - assert.equal(a.y0(), 1); - }, - "y0 can be defined as a function": function(area) { - var a = area().y0(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 1; } - assert.pathEqual(a.call(t, [[1, 2], [4, 3]]), "M1,2L4,3L4,1L1,1Z"); - assert.deepEqual(dd, [[1, 2], [4, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t], "expected this, got {actual}"); - }, - - "y1 defaults to a function accessor": function(area) { - var a = area(); - assert.pathEqual(a([[1, 2], [4, 3]]), "M1,2L4,3L4,0L1,0Z"); - assert.typeOf(a.y1(), "function"); - }, - "y1 can be defined as a constant": function(area) { - var a = area().y1(1); - assert.pathEqual(a([[1, 2], [4, 3]]), "M1,1L4,1L4,0L1,0Z"); - assert.equal(a.y1(), 1); - }, - "y1 can be defined as a function": function(area) { - var a = area().y1(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 1; } - assert.pathEqual(a.call(t, [[1, 2], [4, 3]]), "M1,1L4,1L4,0L1,0Z"); - assert.deepEqual(dd, [[1, 2], [4, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t], "expected this, got {actual}"); - }, - - "if x0 === x1, x is only evaluated once per point": function(area) { - var a = area().x(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 0; } - assert.pathEqual(a.call(t, [[1, 2], [4, 3]]), "M0,2L0,3L0,0L0,0Z"); - assert.deepEqual(dd, [[1, 2], [4, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t], "expected this, got {actual}"); - }, - "if y0 === y1, y is only evaluated once per point": function(area) { - var a = area().y(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 1; } - assert.pathEqual(a.call(t, [[1, 2], [4, 3]]), "M1,1L4,1L4,1L1,1Z"); - assert.deepEqual(dd, [[1, 2], [4, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t], "expected this, got {actual}"); - }, - - "interpolate defaults to linear": function(area) { - assert.equal(area().interpolate(), "linear"); - }, - "interpolate can be defined as a constant": function(area) { - var a = area().interpolate("step-before"); - assert.pathEqual(a([[0, 0], [1, 1]]), "M0,0V1H1L1,0H0V0Z"); - assert.equal(a.interpolate(), "step-before"); - }, - "invalid interpolates fallback to linear": function(area) { - assert.equal(area().interpolate("__proto__").interpolate(), "linear"); - }, - - "tension defaults to .7": function(area) { - assert.equal(area().tension(), .7); - }, - "tension can be specified as a constant": function(area) { - var a = area().tension(.5); - assert.equal(a.tension(), .5); - }, - - "returns null if input points array is empty": function(area) { - assert.isNull(area()([])); - }, - - "interpolate(linear)": { - "supports linear interpolation": testInterpolation("linear") - }, - - "interpolate(step)": { - "supports step-before interpolation": testInterpolation("step-before", "step-after"), - "supports step-after interpolation": testInterpolation("step-after", "step-before") - }, - - "interpolate(basis)": { - "supports basis interpolation": testInterpolation("basis"), - "supports basis-open interpolation": testInterpolation("basis-open") - }, - - "interpolate(cardinal)": { - "supports cardinal interpolation": testInterpolation("cardinal"), - "supports cardinal-open interpolation": testInterpolation("cardinal-open") - }, - - "interpolate(monotone)": { - "supports monotone interpolation": testInterpolation("monotone") - } - } -}); - -// An area is just two lines, with one reversed. -function testInterpolation(i0, i1) { - if (arguments.length < 2) i1 = i0; - return function(area) { - var a = area().interpolate(i0), - d = [[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]], - l0 = _.svg.line().interpolate(i1).x(a.x0()).y(a.y0()), - l1 = _.svg.line().interpolate(i0).x(a.x1()).y(a.y1()); - assert.pathEqual(a(d), l1(d) + "L" + l0(d.reverse()).substring(1) + "Z"); - }; -} - -suite.export(module); diff --git a/test/svg/axis-test.js b/test/svg/axis-test.js deleted file mode 100644 index ab0e2fec18a71c..00000000000000 --- a/test/svg/axis-test.js +++ /dev/null @@ -1,497 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.axis"); - -suite.addBatch({ - "axis": { - topic: load("svg/axis").document(), - - "scale": { - "defaults to a linear scale": function(d3) { - var a = d3.svg.axis(), - x = a.scale(); - assert.deepEqual(x.domain(), [0, 1]); - assert.deepEqual(x.range(), [0, 1]); - assert.equal(x(0.5), 0.5); - }, - "can be defined as a scale object": function(d3) { - var x = _.scale.linear(), - a = d3.svg.axis().scale(x); - assert.equal(a.scale(), x); - }, - "can be a polylinear scale": function(d3) { - var x = _.scale.linear().domain([0, 1, 10]).range([2, 20, 200]), - a = d3.svg.axis().scale(x), - g = d3.select("body").html("").append("g").call(a), - path = g.selectAll("path"); - assert.inDelta(g.selectAll(".tick").data(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1e-4); - assert.inDelta(g.selectAll(".tick").data().map(x), [2, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200], 1e-4); - assert.equal(path.attr("d"), "M2,6V0H200V6"); - }, - "can be an ordinal scale": function(d3) { - var x = _.scale.ordinal().domain(["A", "B", "C"]).rangeBands([10, 90]), - a = d3.svg.axis().scale(x), - g = d3.select("body").html("").append("g").call(a), - path = g.selectAll("path"); - assert.deepEqual(g.selectAll(".tick").data(), ["A", "B", "C"]); - assert.inDelta(g.selectAll(".tick").data().map(x), [10, 36.6667, 63.3333], 1e-4); - assert.equal(path.attr("d"), "M10,6V0H90V6"); - }, - "can be an ordinal scale with explicit range": function(d3) { - var x = _.scale.ordinal().domain(["A", "B", "C"]).range([10, 50, 90]), - a = d3.svg.axis().scale(x), - g = d3.select("body").html("").append("g").call(a), - path = g.selectAll("path"); - assert.deepEqual(g.selectAll(".tick").data(), ["A", "B", "C"]); - assert.deepEqual(g.selectAll(".tick").data().map(x), [10, 50, 90]); - assert.equal(path.attr("d"), "M10,6V0H90V6"); - }, - "can be a quantize scale": function(d3) { - var x = _.scale.quantize().domain([0, 10]).range([10, 50, 90]), - a = d3.svg.axis().scale(x), - g = d3.select("body").html("").append("g").call(a); - assert.inDelta(g.selectAll(".tick").data(), [0, 10], 1e-4); - assert.deepEqual(g.selectAll(".tick").data().map(x), [10, 90]); - assert.equal(g.select("path").attr("d"), "M10,6V0H90V6"); - }, - "can be a quantile scale": function(d3) { - var x = _.scale.quantile().domain([6, 3, 5, 2, 7, 8, 4, 0, 1, 9]).range([10, 50, 90]), - a = d3.svg.axis().scale(x), - g = d3.select("body").html("").append("g").call(a); - assert.inDelta(g.selectAll(".tick").data(), [0, 3, 6], 1e-4); - assert.inDelta(g.selectAll(".tick").data().map(x), [10, 50, 90], 1e-4); - assert.equal(g.select("path").attr("d"), "M10,6V0H90V6"); - }, - "can be a threshold scale": function(d3) { - var x = _.scale.threshold().domain([4, 5, 6]).range([0, 30, 60, 90]), - a = d3.svg.axis().scale(x), - g = d3.select("body").html("").append("g").call(a); - assert.inDelta(g.selectAll(".tick").data(), [4, 5, 6], 1e-4); - assert.inDelta(g.selectAll(".tick").data().map(x), [30, 60, 90], 1e-4); - assert.equal(g.select("path").attr("d"), "M0,6V0H90V6"); - } - }, - - "orient": { - "defaults to bottom": function(d3) { - var a = d3.svg.axis(); - assert.equal(a.orient(), "bottom"); - }, - "defaults to bottom when an invalid orientation is specified": function(d3) { - var a = d3.svg.axis().orient("invalid"); - assert.equal(a.orient(), "bottom"); - }, - "coerces to a string": function(d3) { - var a = d3.svg.axis().orient({toString: function() { return "left"; }}); - assert.equal(a.orient(), "left"); - }, - "supports top orientation": function(d3) { - var a = d3.svg.axis().orient("top"), - g = d3.select("body").html("").append("g").call(a), - tick = g.select("g:nth-child(3)"), - text = tick.select("text"), - line = tick.select("line"), - path = g.select("path.domain"); - assert.equal(tick.attr("transform"), "translate(0.2,0)"); - assert.equal(text.attr("y"), -9); - assert.equal(text.attr("dy"), "0em"); - assert.equal(text.style("text-anchor"), "middle"); - assert.equal(text.text(), "0.2"); - assert.equal(line.attr("y2"), -6); - assert.equal(path.attr("d"), "M0,-6V0H1V-6"); - }, - "supports right orientation": function(d3) { - var a = d3.svg.axis().orient("right"), - g = d3.select("body").html("").append("g").call(a), - tick = g.select("g:nth-child(3)"), - text = tick.select("text"), - line = tick.select("line"), - path = g.select("path.domain"); - assert.equal(tick.attr("transform"), "translate(0,0.2)"); - assert.equal(text.attr("x"), 9); - assert.equal(text.attr("dy"), ".32em"); - assert.equal(text.style("text-anchor"), "start"); - assert.equal(text.text(), "0.2"); - assert.equal(line.attr("x2"), 6); - assert.equal(path.attr("d"), "M6,0H0V1H6"); - }, - "supports bottom orientation": function(d3) { - var a = d3.svg.axis().orient("bottom"), - g = d3.select("body").html("").append("g").call(a), - tick = g.select("g:nth-child(3)"), - text = tick.select("text"), - line = tick.select("line"), - path = g.select("path.domain"); - assert.equal(tick.attr("transform"), "translate(0.2,0)"); - assert.equal(text.attr("y"), 9); - assert.equal(text.attr("dy"), ".71em"); - assert.equal(text.style("text-anchor"), "middle"); - assert.equal(text.text(), "0.2"); - assert.equal(line.attr("y2"), 6); - assert.equal(path.attr("d"), "M0,6V0H1V6"); - }, - "supports left orientation": function(d3) { - var a = d3.svg.axis().orient("left"), - g = d3.select("body").html("").append("g").call(a), - tick = g.select("g:nth-child(3)"), - text = tick.select("text"), - line = tick.select("line"), - path = g.select("path.domain"); - assert.equal(tick.attr("transform"), "translate(0,0.2)"); - assert.equal(text.attr("x"), -9); - assert.equal(text.attr("dy"), ".32em"); - assert.equal(text.style("text-anchor"), "end"); - assert.equal(text.text(), "0.2"); - assert.equal(line.attr("x2"), -6); - assert.equal(path.attr("d"), "M-6,0H0V1H-6"); - } - }, - - "tickSize": { - "defaults to six pixels": function(d3) { - var a = d3.svg.axis(); - assert.strictEqual(a.tickSize(), 6); - }, - "can be defined as a number": function(d3) { - var a = d3.svg.axis().tickSize(3); - assert.strictEqual(a.tickSize(), 3); - }, - "coerces input values to numbers": function(d3) { - var a = d3.svg.axis().tickSize("3"); - assert.strictEqual(a.tickSize(), 3); - assert.strictEqual(a.innerTickSize(), 3); - assert.strictEqual(a.outerTickSize(), 3); - a.tickSize("4", "5"); - assert.strictEqual(a.tickSize(), 4); - assert.strictEqual(a.innerTickSize(), 4); - assert.strictEqual(a.outerTickSize(), 5); - }, - "with no arguments, returns the inner tick size": function(d3) { - var a = d3.svg.axis().innerTickSize(10); - assert.strictEqual(a.tickSize(), 10); - }, - "with one argument, specifies both the inner and outer tick size": function(d3) { - var a = d3.svg.axis().tickSize(10); - assert.strictEqual(a.innerTickSize(), 10); - assert.strictEqual(a.outerTickSize(), 10); - }, - "with two arguments, specifies inner and outer tick sizes": function(d3) { - var a = d3.svg.axis().tickSize(2, 4); - assert.strictEqual(a.innerTickSize(), 2); - assert.strictEqual(a.outerTickSize(), 4); - }, - "with three arguments (for backwards compatibility), specifies the inner and outer tick sizes": function(d3) { - var a = d3.svg.axis().tickSize(1, 2, 3); - assert.strictEqual(a.innerTickSize(), 1); - assert.strictEqual(a.outerTickSize(), 3); - } - }, - - "innerTickSize": { - "defaults to six pixels": function(d3) { - var a = d3.svg.axis(); - assert.strictEqual(a.innerTickSize(), 6); - }, - "can be defined as a number": function(d3) { - var a = d3.svg.axis().innerTickSize(3); - assert.strictEqual(a.innerTickSize(), 3); - }, - "when changed, does not affect the outer tick size": function(d3) { - var a = d3.svg.axis().innerTickSize(3); - assert.strictEqual(a.outerTickSize(), 6); - }, - "coerces the specified value to a number": function(d3) { - var a = d3.svg.axis().innerTickSize("3"); - assert.strictEqual(a.innerTickSize(), 3); - }, - "with no arguments, returns the outer tick size": function(d3) { - var a = d3.svg.axis().outerTickSize(10); - assert.strictEqual(a.outerTickSize(), 10); - }, - "affects the generated tick lines": function(d3) { - var a = d3.svg.axis().innerTickSize(3), - g = d3.select("body").html("").append("g").call(a), - line = g.selectAll("g line"); - line.each(function() { - assert.equal(d3.select(this).attr("y2"), 3); - }); - }, - "if negative, labels are placed on the opposite end": function(d3) { - var a = d3.svg.axis().innerTickSize(-80), - g = d3.select("body").html("").append("g").call(a), - line = g.selectAll("g line"), - text = g.selectAll("g text"); - line.each(function() { - assert.equal(d3.select(this).attr("y2"), -80); - }); - text.each(function() { - assert.equal(d3.select(this).attr("y"), 3); - }); - } - }, - - "outerTickSize": { - "defaults to six pixels": function(d3) { - var a = d3.svg.axis(); - assert.strictEqual(a.outerTickSize(), 6); - }, - "can be defined as a number": function(d3) { - var a = d3.svg.axis().outerTickSize(3); - assert.strictEqual(a.outerTickSize(), 3); - }, - "when changed, does not affect the inner tick size": function(d3) { - var a = d3.svg.axis().outerTickSize(3); - assert.strictEqual(a.innerTickSize(), 6); - }, - "coerces the specified value to a number": function(d3) { - var a = d3.svg.axis().outerTickSize("3"); - assert.strictEqual(a.outerTickSize(), 3); - }, - "with no arguments, returns the inner tick size": function(d3) { - var a = d3.svg.axis().innerTickSize(10); - assert.strictEqual(a.innerTickSize(), 10); - }, - "affects the generated domain path": function(d3) { - var a = d3.svg.axis().tickSize(3), - g = d3.select("body").html("").append("g").call(a), - path = g.select("path.domain"); - assert.equal(path.attr("d"), "M0,3V0H1V3"); - }, - "with three arguments, specifies end tick size and ignores minor tick size": function(d3) { - var a = d3.svg.axis().tickSize(6, 3, 9), - g = d3.select("body").html("").append("g").call(a), - path = g.selectAll("path"); - assert.equal(path.attr("d"), "M0,9V0H1V9"); - } - }, - - "tickPadding": { - "defaults to three pixels": function(d3) { - var a = d3.svg.axis(); - assert.equal(a.tickPadding(), 3); - }, - "can be defined as a number": function(d3) { - var a = d3.svg.axis().tickPadding(6); - assert.equal(a.tickPadding(), 6); - }, - "coerces input value to a number": function(d3) { - var a = d3.svg.axis().tickPadding("6"); - assert.strictEqual(a.tickPadding(), 6); - }, - "affects the generated tick labels": function(d3) { - var a = d3.svg.axis().tickSize(2).tickPadding(7), - g = d3.select("body").html("").append("g").call(a), - text = g.selectAll("g text"); - text.each(function() { - assert.equal(d3.select(this).attr("y"), 9); - }); - } - }, - - "ticks": { - "defaults to [10]": function(d3) { - var a = d3.svg.axis(); - assert.deepEqual(a.ticks(), [10]); - }, - "can be defined as any arguments": function(d3) { - var b = {}, a = d3.svg.axis().ticks(b, 42), t = a.ticks(); - assert.equal(t[0], b); - assert.equal(t[1], 42); - assert.equal(t.length, 2); - }, - "passes any arguments to the scale's ticks function": function(d3) { - var x = _.scale.linear(), b = {}, a = d3.svg.axis().ticks(b, "%").scale(x), aa = [], - g = d3.select("body").html("").append("g"); - x.ticks = function() { aa.push(arguments); return [42]; }; - g.call(a); - assert.equal(aa.length, 1); - assert.equal(aa[0].length, 2); - assert.equal(aa[0][0], b); - assert.equal(aa[0][1], "%"); - }, - "passes any arguments to the scale's tickFormat function": function(d3) { - var b = {}, - x = _.scale.linear(), - a = d3.svg.axis().scale(x).ticks(b, "%"), - g = d3.select("body").html("").append("g"), - aa = []; - - x.tickFormat = function() { - aa.push(arguments); - return String; - }; - - g.call(a); - assert.equal(aa.length, 1); - assert.equal(aa[0].length, 2); - assert.equal(aa[0][0], b); - assert.equal(aa[0][1], "%"); - }, - "affects the generated ticks": function(d3) { - var a = d3.svg.axis().ticks(20, "%"), - g = d3.select("body").html("").append("g").call(a), - t = g.selectAll("g"); - assert.equal(t[0].length, 21); - assert.equal(t[0][0].textContent, "0%"); - }, - "only substitutes precision if not specified": function(d3) { - var a = d3.svg.axis().ticks(20, ".5%"), - g = d3.select("body").html("").append("g").call(a), - t = g.selectAll("g"); - assert.equal(t[0].length, 21); - assert.equal(t[0][0].textContent, "0.00000%"); - } - }, - - "tickValues": { - "defaults to null": function(d3) { - var a = d3.svg.axis().tickValues(); - assert.isNull(a); - }, - "can be given as array of positions": function(d3) { - var l = [1, 2.5, 3], a = d3.svg.axis().tickValues(l), t = a.tickValues(); - assert.equal(t, l); - assert.equal(t.length, 3); - }, - "does not change the tick arguments": function(d3) { - var b = {}, a = d3.svg.axis().ticks(b, 42).tickValues([10]), t = a.ticks(); - assert.equal(t[0], b); - assert.equal(t[1], 42); - assert.equal(t.length, 2); - }, - "does not change the arguments passed to the scale's tickFormat function": function(d3) { - var x = _.scale.linear(), - a = d3.svg.axis().scale(x).ticks(10).tickValues([1, 2, 3]), - g = d3.select("body").html("").append("g"), - aa = []; - - x.tickFormat = function() { - aa.push(arguments); - return String; - }; - - g.call(a); - assert.equal(aa.length, 1); - assert.equal(aa[0].length, 1); - assert.equal(aa[0][0], 10); - }, - "affects the generated ticks": function(d3) { - var a = d3.svg.axis().ticks(20), - g = d3.select("body").html("").append("g").call(a), - t = g.selectAll("g"); - assert.equal(t[0].length, 21); - } - }, - - "tickSubdivide": { - "is deprecated and does nothing": function(d3) { - var a = d3.svg.axis(); - assert.equal(a.tickSubdivide(), 0); - assert.strictEqual(a.tickSubdivide(1), a); - assert.equal(a.tickSubdivide(), 0); - } - }, - - "tickFormat": { - "defaults to null": function(d3) { - var a = d3.svg.axis(); - assert.isTrue(a.tickFormat() == null); - }, - "when null, uses the scale's tick format": function(d3) { - var x = _.scale.linear(), a = d3.svg.axis().scale(x), - g = d3.select("body").html("").append("g"); - - x.tickFormat = function() { - return function(d) { - return "foo-" + d; - }; - }; - - g.call(a); - var t = g.selectAll("g text"); - assert.equal(t.text(), "foo-0"); - }, - "affects the generated tick labels": function(d3) { - var a = d3.svg.axis().tickFormat(d3.format("+.2%")), - g = d3.select("body").html("").append("g").call(a), - t = g.selectAll("g text"); - assert.equal(t.text(), "+0.00%"); - }, - "can be set to a constant": function(d3) { - var a = d3.svg.axis().tickFormat("I'm a tick!"), - g = d3.select("body").html("").append("g").call(a), - t = g.selectAll("g text"); - assert.equal(t.text(), "I'm a tick!"); - }, - "can be set to a falsey constant": function(d3) { - var a = d3.svg.axis().tickFormat(""), - g = d3.select("body").html("").append("g").call(a), - t = g.selectAll("g text"); - assert.equal(t.text(), ""); - } - }, - - "enter": { - "generates a new domain path": function(d3) { - var a = d3.svg.axis(), - g = d3.select("body").html("").append("g").call(a), - path = g.selectAll("path.domain"); - assert.equal(path[0].length, 1); - assert.equal(path.attr("d"), "M0,6V0H1V6"); - assert.isNull(path.node().nextSibling); - }, - "generates new tick marks with labels": function(d3) { - var a = d3.svg.axis(), - g = d3.select("body").html("").append("g").call(a), - x = _.scale.linear(), - tick = g.selectAll("g"), - ticks = x.ticks(10), - tickFormat = x.tickFormat(10); - assert.equal(tick[0].length, ticks.length); - tick.each(function(d, i) { - var t = d3.select(this); - assert.isFalse(t.select("line").empty()); - assert.isFalse(t.select("text").empty()); - assert.equal(t.select("text").text(), tickFormat(ticks[i])); - }); - } - }, - - "update": { - "updates the domain path": function(d3) { - var a = d3.svg.axis(), - g = d3.select("body").html("").append("g").call(a); - a.scale().domain([0, 2]).range([1, 2]); - a.tickSize(3); - g.call(a); - var path = g.selectAll("path.domain"); - assert.equal(path[0].length, 1); - assert.equal(path.attr("d"), "M1,3V0H2V3"); - assert.domEqual(path.node().nextSibling, null); - }, - "enters, exits and updates tick marks": function(d3) { - var a = d3.svg.axis(), - g = d3.select("body").html("").append("g").call(a), - x = d3.scale.linear().domain([1, 1.5]); - a.scale().domain(x.domain()); - a.tickSize(3).tickPadding(9); - g.call(a); - var tick = g.selectAll("g"), - ticks = x.ticks(10), - tickFormat = x.tickFormat(10); - assert.equal(tick[0].length, ticks.length); - tick.each(function(d, i) { - var t = d3.select(this); - assert.isFalse(t.select("line").empty()); - assert.isFalse(t.select("text").empty()); - assert.equal(t.select("text").text(), tickFormat(ticks[i])); - }); - } - } - } -}); - -suite.export(module); diff --git a/test/svg/brush-test.js b/test/svg/brush-test.js deleted file mode 100644 index c64abfefbeddde..00000000000000 --- a/test/svg/brush-test.js +++ /dev/null @@ -1,114 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.brush"); - -suite.addBatch({ - "brush": { - topic: load("svg/brush").expression("d3.svg.brush").document(), - - "x": { - "defaults to null": function(brush) { - assert.isNull(brush().x()); - } - }, - - "y": { - "defaults to null": function(brush) { - assert.isNull(brush().y()); - } - }, - - "clamp": { - "returns null when no scales are attached": function(brush) { - assert.isNull(brush().clamp()); - }, - "returns a single boolean if only x is defined": function(brush) { - var b = brush().x(_.scale.linear()); - assert.isTrue(b.clamp()); - }, - "returns a single boolean if only y is defined": function(brush) { - var b = brush().y(_.scale.linear()); - assert.isTrue(b.clamp()); - }, - "returns one-dimensional array if both x and y are defined": function(brush) { - var b = brush().x(_.scale.linear()).y(_.scale.linear()); - assert.deepEqual(b.clamp(), [true, true]); - }, - "takes a single boolean if only x is defined": function(brush) { - var b = brush().x(_.scale.linear()).clamp(false); - assert.isFalse(b.clamp()); - }, - "takes a single boolean if only y is defined": function(brush) { - var b = brush().y(_.scale.linear()).clamp(false); - assert.isFalse(b.clamp()); - }, - "takes a one-dimensional array if both x and y are defined": function(brush) { - var b = brush().x(_.scale.linear()).y(_.scale.linear()).clamp([false, true]); - assert.deepEqual(b.clamp(), [false, true]); - b.clamp([true, false]); - assert.deepEqual(b.clamp(), [true, false]); - } - }, - - "extent": { - "returns null when no scales are attached": function(brush) { - assert.isNull(brush().extent()); - }, - "returns a one-dimensional array if only x is defined": function(brush) { - var b = brush().x(_.scale.linear()); - assert.deepEqual(b.extent(), [0, 0]); - }, - "takes a one-dimensional array if only x is defined": function(brush) { - var b = brush().x(_.scale.linear()).extent([0.1, 0.4]); - assert.deepEqual(b.extent(), [0.1, 0.4]); - }, - "returns a one-dimensional array if only y is defined": function(brush) { - var b = brush().y(_.scale.linear()); - assert.deepEqual(b.extent(), [0, 0]); - }, - "takes a one-dimensional array if only y is defined": function(brush) { - var b = brush().y(_.scale.linear()).extent([0.1, 0.4]); - assert.deepEqual(b.extent(), [0.1, 0.4]); - }, - "returns a two-dimensional array if x and y are defined": function(brush) { - var b = brush().x(_.scale.linear()).y(_.scale.linear()); - assert.deepEqual(b.extent(), [[0, 0], [0, 0]]); - }, - "takes a two-dimensional array if x and y are defined": function(brush) { - var b = brush().x(_.scale.linear()).y(_.scale.linear()).extent([[0.1, 0.2], [0.3, 0.4]]); - assert.deepEqual(b.extent(), [[0.1, 0.2], [0.3, 0.4]]); - }, - "preserves the set extent exactly": function(brush) { - var lo = new Number(0.1), - hi = new Number(0.3), - b = brush().x(_.scale.linear()).extent([lo, hi]), - extent = b.extent(); - assert.strictEqual(extent[0], lo); - assert.strictEqual(extent[1], hi); - } - }, - - "empty": { - "returns true if and only if any defined extent is empty": function(brush) { - var b = brush(); - assert.strictEqual(b.empty(), false); // x and y are undefined - var b = brush().x(_.scale.linear()); - assert.strictEqual(b.empty(), true); // x is empty, y is undefined - assert.strictEqual(b.extent([0, 1]).empty(), false); // x is non-empty, y is undefined - var b = brush().y(_.scale.linear()); - assert.strictEqual(b.empty(), true); // x is undefined, y is empty - assert.strictEqual(b.extent([0, 1]).empty(), false); // x is undefined, y is non-empty - var b = brush().x(_.scale.linear()).y(_.scale.linear()); - assert.strictEqual(b.empty(), true); // x is empty, y is empty - assert.strictEqual(b.extent([[0, 0], [1, 0]]).empty(), true); // x is non-empty, y is empty - assert.strictEqual(b.extent([[0, 0], [0, 1]]).empty(), true); // x is empty, y is non-empty - assert.strictEqual(b.extent([[0, 0], [1, 1]]).empty(), false); // x is non-empty, y is non-empty - } - } - } -}); - -suite.export(module); diff --git a/test/svg/diagonal-test.js b/test/svg/diagonal-test.js deleted file mode 100644 index 4a7ae51aba2633..00000000000000 --- a/test/svg/diagonal-test.js +++ /dev/null @@ -1,62 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.diagonal"); - -suite.addBatch({ - "diagonal": { - topic: load("svg/diagonal").expression("d3.svg.diagonal"), - - "source defaults to a function accessor": function(diagonal) { - var d = diagonal().target({x:5, y:5}); - assert.pathEqual(d({source: {x:1, y:1}}), "M1,1C1,3 5,3 5,5"); - assert.pathEqual(d({source: {x:5, y:1}}), "M5,1C5,3 5,3 5,5"); - }, - "source can be defined as a constant": function(diagonal) { - var d = diagonal().target({x:5, y:5}); - assert.pathEqual(d.source({x:1, y:1})(), "M1,1C1,3 5,3 5,5"); - assert.pathEqual(d.source({x:5, y:1})(), "M5,1C5,3 5,3 5,5"); - }, - "source can be defined as a function of data or index": function(diagonal) { - var d = diagonal().source(f).target({x:5, y:5}), o = {}, t = {}, dd, ii, tt; - function f(d,i) { dd = d; ii = i; tt = this; return {x:42, y:42}; } - assert.pathEqual(d.call(t, o, 2), "M42,42C42,23.500000 5,23.500000 5,5"); - - assert.equal(dd, o, "expected data, got {actual}"); - assert.equal(ii, 2, "expected data, got {actual}"); - assert.equal(tt, t, "expected data, got {actual}"); - }, - "target defaults to a function accessor": function(diagonal) { - var d = diagonal().source({x:1, y:1}); - assert.pathEqual(d({target: {x:5, y:5}}), "M1,1C1,3 5,3 5,5"); - assert.pathEqual(d({target: {x:5, y:1}}), "M1,1C1,1 5,1 5,1"); - }, - "target can be defined as a constant": function(diagonal) { - var d = diagonal().source({x:1, y:1}); - assert.pathEqual(d.target({x:5, y:5})(), "M1,1C1,3 5,3 5,5"); - assert.pathEqual(d.target({x:5, y:1})(), "M1,1C1,1 5,1 5,1"); - }, - "target can be defined as a function of data or index": function(diagonal) { - var d = diagonal().source({x:1, y:1}).target(f), o = {}, t = {}, dd, ii, tt; - function f(d,i) { dd = d; ii = i; tt = this; return {x:42, y:42}; } - assert.pathEqual(d.call(t, o, 2), "M1,1C1,21.500000 42,21.500000 42,42"); - - assert.equal(dd, o, "expected data, got {actual}"); - assert.equal(ii, 2, "expected data, got {actual}"); - assert.equal(tt, t, "expected data, got {actual}"); - }, - "projection defaults to identity": function(diagonal) { - var d = diagonal(); - assert.deepEqual(d.projection()({x:1, y:1}),[1, 1]); - }, - "custom projection function can be set": function(diagonal) { - var d = diagonal().source({x:1, y:1}).target({x:5, y:5}); - assert.pathEqual(d.projection(function(d) { - return [d.x * 2, d.y * 2]; - })(),"M2,2C2,6 10,6 10,10"); - } - } -}); - -suite.export(module); diff --git a/test/svg/line-radial-test.js b/test/svg/line-radial-test.js deleted file mode 100644 index 6d7e358f105aa4..00000000000000 --- a/test/svg/line-radial-test.js +++ /dev/null @@ -1,120 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.line.radial"); - -suite.addBatch({ - "line.radial": { - topic: load("svg/line-radial").expression("d3.svg.line.radial"), - - "radius defaults to a function accessor": function(line) { - var l = line(); - assert.pathEqual(l([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.82941969615793,-10.806046117362794L18.185948536513635,8.32293673094285L1.4112000805986715,9.899924966004454"); - assert.typeOf(l.radius(), "function"); - }, - "radius can be defined as a constant": function(line) { - var l = line().radius(30); - assert.pathEqual(l([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-30L25.244129544236895,-16.20906917604419L27.278922804770453,12.484405096414275L4.233600241796014,29.699774898013363"); - assert.equal(l.radius(), 30); - }, - "radius can be defined as a function": function(line) { - var l = line().radius(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 30; } - assert.pathEqual(l.call(t, [[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-30L25.244129544236895,-16.20906917604419L27.278922804770453,12.484405096414275L4.233600241796014,29.699774898013363"); - assert.deepEqual(dd, [[10, 0], [20, 1], [20, 2], [10, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1, 2, 3], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t, t, t], "expected this, got {actual}"); - }, - - "angle defaults to a function accessor": function(line) { - var l = line(); - assert.pathEqual(l([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10L16.82941969615793,-10.806046117362794L18.185948536513635,8.32293673094285L1.4112000805986715,9.899924966004454"); - assert.typeOf(l.angle(), "function"); - }, - "angle can be defined as a constant": function(line) { - var l = line().angle(Math.PI / 2); - assert.pathEqual(l([[10, 0], [20, 1], [20, 2], [10, 3]]), "M10,0L20,0L20,0L10,0"); - assert.equal(l.angle(), Math.PI / 2); - }, - "angle can be defined as a function": function(line) { - var l = line().angle(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return Math.PI / 2; } - assert.pathEqual(l.call(t, [[10, 0], [20, 1], [20, 2], [10, 3]]), "M10,0L20,0L20,0L10,0"); - assert.deepEqual(dd, [[10, 0], [20, 1], [20, 2], [10, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1, 2, 3], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t, t, t], "expected this, got {actual}"); - }, - "angle is defined in radians, with zero at 12 o'clock": function(line) { - var l = line().angle(0); - assert.pathEqual(l([[10, Math.PI], [20, Math.PI / 3]]), "M0,-10L0,-20"); - assert.equal(l.angle(), 0); - }, - - "interpolate defaults to linear": function(line) { - assert.equal(line().interpolate(), "linear"); - }, - "interpolate can be defined as a constant": function(line) { - var l = line().interpolate("cardinal"); - assert.pathEqual(l([[10, 0], [20, 1], [20, 2], [10, 3]]), "M0,-10Q15.010824842506567,-12.638339790457078,16.82941969615793,-10.806046117362794C19.557311976634978,-8.057605607721365,20.498681478847523,5.217041068437762,18.185948536513635,8.32293673094285Q16.64412657495771,10.393533839279574,1.4112000805986715,9.899924966004454"); - assert.equal(l.interpolate(), "cardinal"); - }, - - "tension defaults to .7": function(line) { - assert.equal(line().tension(), .7); - }, - "tension can be specified as a constant": function(line) { - var l = line().tension(.5); - assert.equal(l.tension(), .5); - }, - - "returns null if input points array is empty": function(line) { - assert.isNull(line()([])); - }, - - "interpolate(linear)": { - "supports linear interpolation": testInterpolation("linear") - }, - - "interpolate(step)": { - "supports step-before interpolation": testInterpolation("step-before"), - "supports step-after interpolation": testInterpolation("step-after") - }, - - "interpolate(basis)": { - "supports basis interpolation": testInterpolation("basis"), - "supports basis-open interpolation": testInterpolation("basis-open"), - "supports basis-closed interpolation": testInterpolation("basis-closed") - }, - - "interpolate(bundle)": { - "supports bundle interpolation": testInterpolation("bundle") - }, - - "interpolate(cardinal)": { - "supports cardinal interpolation": testInterpolation("cardinal"), - "supports cardinal-open interpolation": testInterpolation("cardinal-open"), - "supports cardinal-closed interpolation": testInterpolation("cardinal-closed") - }, - - "interpolate(monotone)": { - "supports monotone interpolation": testInterpolation("monotone") - } - } -}); - -// A radial line is just a transformation of a Cartesian line. -function testInterpolation(interpolate) { - var data = [[10, 0], [20, 1], [20, 2], [10, 3]]; - - var cartesian = _.svg.line() - .x(function(d) { return d[0] * Math.cos(d[1] - Math.PI / 2); }) - .y(function(d) { return d[0] * Math.sin(d[1] - Math.PI / 2); }); - - return function(radial) { - assert.pathEqual(radial().interpolate(interpolate)(data), cartesian.interpolate(interpolate)(data)); - }; -} - -suite.export(module); diff --git a/test/svg/line-test.js b/test/svg/line-test.js deleted file mode 100644 index 010189eb1d1e4f..00000000000000 --- a/test/svg/line-test.js +++ /dev/null @@ -1,207 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.line"); - -suite.addBatch({ - "line": { - topic: load("svg/line").expression("d3.svg.line"), - - "x defaults to a function accessor": function(line) { - var l = line(); - assert.pathEqual(l([[1, 2], [4, 3]]), "M1,2L4,3"); - assert.typeOf(l.x(), "function"); - }, - "x can be defined as a constant": function(line) { - var l = line().x(0); - assert.pathEqual(l([[1, 2], [4, 3]]), "M0,2L0,3"); - assert.equal(l.x(), 0); - }, - "x can be defined as a function": function(line) { - var l = line().x(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 0; } - assert.pathEqual(l.call(t, [[1, 2], [4, 3]]), "M0,2L0,3"); - assert.deepEqual(dd, [[1, 2], [4, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t], "expected this, got {actual}"); - }, - - "y defaults to a function accessor": function(line) { - var l = line(); - assert.pathEqual(l([[1, 2], [4, 3]]), "M1,2L4,3"); - assert.typeOf(l.y(), "function"); - }, - "y can be defined as a constant": function(line) { - var l = line().y(0); - assert.pathEqual(l([[1, 2], [4, 3]]), "M1,0L4,0"); - assert.equal(l.y(), 0); - }, - "y can be defined as a function": function(line) { - var l = line().y(f), t = {}, dd = [], ii = [], tt = []; - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return 0; } - assert.pathEqual(l.call(t, [[1, 2], [4, 3]]), "M1,0L4,0"); - assert.deepEqual(dd, [[1, 2], [4, 3]], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.deepEqual(tt, [t, t], "expected this, got {actual}"); - }, - - "interpolate defaults to linear": function(line) { - assert.equal(line().interpolate(), "linear"); - }, - "interpolate can be defined as a constant": function(line) { - var l = line().interpolate("step-before"); - assert.pathEqual(l([[0, 0], [1, 1]]), "M0,0V1H1"); - assert.equal(l.interpolate(), "step-before"); - }, - "interpolate can be defined as a function": function(line) { - var l = line().interpolate(interpolate); - assert.pathEqual(l([[0, 0], [1, 1]]), "M0,0T1,1"); - assert.equal(l.interpolate(), interpolate); - - function interpolate(points) { - return points.join("T"); - } - }, - "invalid interpolates fallback to linear": function(line) { - assert.equal(line().interpolate("__proto__").interpolate(), "linear"); - }, - - "tension defaults to .7": function(line) { - assert.equal(line().tension(), .7); - }, - "tension can be specified as a constant": function(line) { - var l = line().tension(.5); - assert.equal(l.tension(), .5); - }, - - "returns null if input points array is empty": function(line) { - assert.isNull(line()([])); - }, - - "interpolate(linear)": { - "supports linear interpolation": function(line) { - var l = line().interpolate("linear"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M0,0L1,1L2,0L3,1L4,0"); - } - }, - - "interpolate(step)": { - "supports step-before interpolation": function(line) { - var l = line().interpolate("step-before"); - assert.pathEqual(l([[0, 0]]), "M0,0"); - assert.pathEqual(l([[0, 0], [1, 1]]), "M0,0V1H1"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0]]), "M0,0V1H1V0H2"); - }, - "supports step interpolation": function(line) { - var l = line().interpolate("step"); - assert.pathEqual(l([[0, 0]]), "M0,0"); - assert.pathEqual(l([[0, 0], [1, 1]]), "M0,0H0.5V1H1"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0]]), "M0,0H0.5V1H1.5V0H2"); - }, - "supports step-after interpolation": function(line) { - var l = line().interpolate("step-after"); - assert.pathEqual(l([[0, 0]]), "M0,0"); - assert.pathEqual(l([[0, 0], [1, 1]]), "M0,0H1V1"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0]]), "M0,0H1V1H2V0"); - } - }, - - "interpolate(basis)": { - "supports basis interpolation": function(line) { - var l = line().interpolate("basis"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M0,0L0.16666666666666666,0.16666666666666666C0.3333333333333333,0.3333333333333333,0.6666666666666666,0.6666666666666666,1,0.6666666666666666C1.3333333333333333,0.6666666666666666,1.6666666666666665,0.3333333333333333,2,0.3333333333333333C2.333333333333333,0.3333333333333333,2.6666666666666665,0.6666666666666666,3,0.6666666666666666C3.333333333333333,0.6666666666666666,3.6666666666666665,0.3333333333333333,3.833333333333333,0.16666666666666666L4,0"); - }, - "supports basis-open interpolation": function(line) { - var l = line().interpolate("basis-open"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M1,0.6666666666666666C1.3333333333333333,0.6666666666666666,1.6666666666666665,0.3333333333333333,2,0.3333333333333333C2.333333333333333,0.3333333333333333,2.6666666666666665,0.6666666666666666,3,0.6666666666666666"); - }, - "supports basis-closed interpolation": function(line) { - var l = line().interpolate("basis-closed"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M2,0.3333333333333333C2.333333333333333,0.3333333333333333,2.6666666666666665,0.6666666666666666,3,0.6666666666666666C3.333333333333333,0.6666666666666666,3.6666666666666665,0.3333333333333333,3.1666666666666665,0.16666666666666666C2.6666666666666665,0,1.3333333333333333,0,0.8333333333333333,0.16666666666666666C0.3333333333333333,0.3333333333333333,0.6666666666666666,0.6666666666666666,1,0.6666666666666666C1.3333333333333333,0.6666666666666666,1.6666666666666665,0.3333333333333333,2,0.3333333333333333"); - }, - "basis interpolation reverts to linear with fewer than three points": function(line) { - var l = line().interpolate("basis"), d = line(); - assert.pathEqual(l([[0, 0]]), d([[0, 0]])); - assert.pathEqual(l([[0, 0], [1, 1]]), d([[0, 0], [1, 1]])); - }, - "basis-open interpolation reverts to linear with fewer than four points": function(line) { - var l = line().interpolate("basis-open"), d = line(); - assert.pathEqual(l([[0, 0]]), d([[0, 0]])); - assert.pathEqual(l([[0, 0], [1, 1]]), d([[0, 0], [1, 1]])); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0]]), d([[0, 0], [1, 1], [2, 0]])); - }, - "basis-closed interpolation reverts to linear with fewer than three points": function(line) { - var l = line().interpolate("basis-open"), d = line(); - assert.pathEqual(l([[0, 0]]), d([[0, 0]])); - assert.pathEqual(l([[0, 0], [1, 1]]), d([[0, 0], [1, 1]])); - } - }, - - "interpolate(bundle)": { - "supports bundle interpolation": function(line) { - var l = line().interpolate("bundle"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M0,0L0.16666666666666666,0.11666666666666665C0.3333333333333333,0.2333333333333333,0.6666666666666666,0.4666666666666666,1,0.4666666666666666C1.3333333333333333,0.4666666666666666,1.6666666666666665,0.2333333333333333,2,0.2333333333333333C2.333333333333333,0.2333333333333333,2.6666666666666665,0.4666666666666666,3,0.4666666666666666C3.333333333333333,0.4666666666666666,3.6666666666666665,0.2333333333333333,3.833333333333333,0.11666666666666665L4,0"); - }, - "observes the specified tension": function(line) { - var l = line().interpolate("bundle").tension(1); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), line().interpolate("basis")([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]])); - }, - "supports a single-element array": function(line) { - var l = line().interpolate("bundle").tension(1); - assert.pathEqual(l([[0, 0]]), "M0,0"); - } - }, - - "interpolate(cardinal)": { - "supports cardinal interpolation": function(line) { - var l = line().interpolate("cardinal"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M0,0Q0.8,1,1,1C1.3,1,1.7,0,2,0S2.7,1,3,1Q3.2,1,4,0"); - }, - "supports cardinal-open interpolation": function(line) { - var l = line().interpolate("cardinal-open"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M1,1C1.3,1,1.7,0,2,0S2.7,1,3,1"); - }, - "supports cardinal-closed interpolation": function(line) { - var l = line().interpolate("cardinal-closed"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M0,0C-0.45,0.15,0.7,1,1,1S1.7,0,2,0S2.7,1,3,1S4.45,0.15,4,0S0.45,-0.15,0,0"); - }, - "cardinal interpolation reverts to linear with fewer than three points": function(line) { - var l = line().interpolate("cardinal"), d = line(); - assert.pathEqual(l([[0, 0]]), d([[0, 0]])); - assert.pathEqual(l([[0, 0], [1, 1]]), d([[0, 0], [1, 1]])); - }, - "cardinal-open interpolation reverts to linear with fewer than four points": function(line) { - var l = line().interpolate("cardinal-open"), d = line(); - assert.pathEqual(l([[0, 0]]), d([[0, 0]])); - assert.pathEqual(l([[0, 0], [1, 1]]), d([[0, 0], [1, 1]])); - assert.pathEqual(l([[0, 0], [1, 1], [2, 0]]), d([[0, 0], [1, 1], [2, 0]])); - }, - "cardinal-closed interpolation reverts to linear with fewer than three points": function(line) { - var l = line().interpolate("cardinal-open"), d = line(); - assert.pathEqual(l([[0, 0]]), d([[0, 0]])); - assert.pathEqual(l([[0, 0], [1, 1]]), d([[0, 0], [1, 1]])); - }, - "observes the specified tension": function(line) { - var l = line().tension(.5); - assert.pathEqual(l.interpolate("cardinal")([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M0,0Q0.6666666666666667,1,1,1C1.5,1,1.5,0,2,0S2.5,1,3,1Q3.3333333333333335,1,4,0"); - assert.pathEqual(l.interpolate("cardinal-open")([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M1,1C1.5,1,1.5,0,2,0S2.5,1,3,1"); - assert.pathEqual(l.interpolate("cardinal-closed")([[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]), "M0,0C-0.75,0.25,0.5,1,1,1S1.5,0,2,0S2.5,1,3,1S4.75,0.25,4,0S0.75,-0.25,0,0"); - } - }, - - "interpolate(monotone)": { - "supports monotone interpolation": function(line) { - var l = line().interpolate("monotone"); - assert.pathEqual(l([[0, 0], [1, 1], [2, 1], [3, 0], [4, 0]]), "M0,0C0.08333333333333333,0.08333333333333333,0.6666666666666667,1,1,1S1.6666666666666667,1,2,1S2.6666666666666665,0,3,0S3.8333333333333335,0,4,0"); - }, - "monotone interpolation reverts to linear with fewer than three points": function(line) { - var l = line().interpolate("monotone"), d = line(); - assert.pathEqual(l([[0, 0]]), d([[0, 0]])); - assert.pathEqual(l([[0, 0], [1, 1]]), d([[0, 0], [1, 1]])); - } - } - } -}); - -suite.export(module); diff --git a/test/svg/symbol-test.js b/test/svg/symbol-test.js deleted file mode 100644 index 9477a9aedf5c90..00000000000000 --- a/test/svg/symbol-test.js +++ /dev/null @@ -1,91 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.svg.symbol"); - -suite.addBatch({ - "symbol": { - topic: load("svg/symbol").expression("d3.svg.symbol"), - "default symbol is a fixed-size circle": function(symbol) { - var a = symbol(); - assert.pathEqual(a(), "M0,4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,-4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,4.51351666838205Z"); - }, - "size accessor specifies shape area in square pixels": function(symbol) { - var a = symbol().size(Number); - assert.pathEqual(a(0), "M0,0A0,0 0 1,1 0,0A0,0 0 1,1 0,0Z"); - assert.pathEqual(a(Math.PI), "M0,1A1,1 0 1,1 0,-1A1,1 0 1,1 0,1Z"); - assert.pathEqual(a(4 * Math.PI), "M0,2A2,2 0 1,1 0,-2A2,2 0 1,1 0,2Z"); - }, - "size accessor is passed data and index": function(symbol) { - var a = symbol().size(function(d, i) { return d.z * 2 + i; }); - assert.pathEqual(a({z: 0}, 0), "M0,0A0,0 0 1,1 0,0A0,0 0 1,1 0,0Z"); - assert.pathEqual(a({z: Math.PI}, 1), "M0,1.5225997130512636A1.5225997130512636,1.5225997130512636 0 1,1 0,-1.5225997130512636A1.5225997130512636,1.5225997130512636 0 1,1 0,1.5225997130512636Z"); - assert.pathEqual(a({z: 4 * Math.PI}, 2), "M0,2.938812646693828A2.938812646693828,2.938812646693828 0 1,1 0,-2.938812646693828A2.938812646693828,2.938812646693828 0 1,1 0,2.938812646693828Z"); - }, - "supports cross symbol type": function(symbol) { - var a = symbol().type("cross").size(Number); - assert.pathEqual(a(0), "M0,0H0V0H0V0H0V0H0V0H0V0H0Z"); - assert.pathEqual(a(20), "M-3,-1H-1V-3H1V-1H3V1H1V3H-1V1H-3Z"); - }, - "supports diamond symbol type": function(symbol) { - var a = symbol().type("diamond").size(Number); - assert.pathEqual(a(0), "M0,0L0,0 0,0 0,0Z"); - assert.pathEqual(a(10), "M0,-2.9428309563827124L1.6990442448471224,0 0,2.9428309563827124 -1.6990442448471224,0Z"); - }, - "supports square symbol type": function(symbol) { - var a = symbol().type("square").size(Number); - assert.pathEqual(a(0), "M0,0L0,0 0,0 0,0Z"); - assert.pathEqual(a(4), "M-1,-1L1,-1 1,1 -1,1Z"); - assert.pathEqual(a(16), "M-2,-2L2,-2 2,2 -2,2Z"); - }, - "supports triangle-down symbol type": function(symbol) { - var a = symbol().type("triangle-down").size(Number); - assert.pathEqual(a(0), "M0,0L0,0 0,0Z"); - assert.pathEqual(a(10), "M0,2.0808957251439084L2.4028114141347543,-2.0808957251439084 -2.4028114141347543,-2.0808957251439084Z"); - }, - "supports triangle-up symbol type": function(symbol) { - var a = symbol().type("triangle-up").size(Number); - assert.pathEqual(a(0), "M0,0L0,0 0,0Z"); - assert.pathEqual(a(10), "M0,-2.0808957251439084L2.4028114141347543,2.0808957251439084 -2.4028114141347543,2.0808957251439084Z"); - }, - "unknown symbol type defaults to circle": function(symbol) { - var a = symbol().type(String); - assert.pathEqual(a(), "M0,4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,-4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,4.51351666838205Z"); - assert.pathEqual(a("invalid"), "M0,4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,-4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,4.51351666838205Z"); - assert.pathEqual(a("hasOwnProperty"), "M0,4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,-4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,4.51351666838205Z"); - }, - "can specify type accessor as a function": function(symbol) { - var a = symbol().type(String); - assert.pathEqual(a("circle"), "M0,4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,-4.51351666838205A4.51351666838205,4.51351666838205 0 1,1 0,4.51351666838205Z"); - assert.pathEqual(a("cross"), "M-5.366563145999495,-1.7888543819998317H-1.7888543819998317V-5.366563145999495H1.7888543819998317V-1.7888543819998317H5.366563145999495V1.7888543819998317H1.7888543819998317V5.366563145999495H-1.7888543819998317V1.7888543819998317H-5.366563145999495Z"); - assert.pathEqual(a("diamond"), "M0,-7.444838872816797L4.298279727294167,0 0,7.444838872816797 -4.298279727294167,0Z"); - assert.pathEqual(a("square"), "M-4,-4L4,-4 4,4 -4,4Z"); - assert.pathEqual(a("triangle-down"), "M0,5.26429605180997L6.078685485212741,-5.26429605180997 -6.078685485212741,-5.26429605180997Z"); - assert.pathEqual(a("triangle-up"), "M0,-5.26429605180997L6.078685485212741,5.26429605180997 -6.078685485212741,5.26429605180997Z"); - } - }, - "symbolTypes": { - topic: load("svg/symbol").expression("d3.svg.symbolTypes"), - "contains circle": function(types) { - assert.isTrue(types.indexOf("circle") != -1); - }, - "contains cross": function(types) { - assert.isTrue(types.indexOf("cross") != -1); - }, - "contains diamond": function(types) { - assert.isTrue(types.indexOf("diamond") != -1); - }, - "contains square": function(types) { - assert.isTrue(types.indexOf("square") != -1); - }, - "contains triangle-down": function(types) { - assert.isTrue(types.indexOf("triangle-down") != -1); - }, - "contains triangle-up": function(types) { - assert.isTrue(types.indexOf("triangle-up") != -1); - } - } -}); - -suite.export(module); diff --git a/test/test-exports.js b/test/test-exports.js new file mode 100644 index 00000000000000..f7d3e33e0cfc02 --- /dev/null +++ b/test/test-exports.js @@ -0,0 +1,13 @@ +var tape = require("tape-await"), + d3 = require("../"); + +module.exports = function(moduleName) { + var module = require(moduleName); + tape("d3 exports everything from " + moduleName, function(test) { + for (var symbol in module) { + if (symbol !== "version") { + test.equal(symbol in d3, true, moduleName + " export " + symbol); + } + } + }); +}; diff --git a/test/time/day-test.js b/test/time/day-test.js deleted file mode 100644 index c408b5ae9447cc..00000000000000 --- a/test/time/day-test.js +++ /dev/null @@ -1,178 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.day"); - -suite.addBatch({ - "day": { - topic: load("time/day").expression("d3.time.day"), - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns midnights": function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23)), local(2010, 11, 31)); - assert.deepEqual(floor(local(2011, 00, 01, 00)), local(2011, 00, 01)); - assert.deepEqual(floor(local(2011, 00, 01, 01)), local(2011, 00, 01)); - }, - "observes start of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 02, 13, 07)), local(2011, 02, 12)); - assert.deepEqual(floor(utc(2011, 02, 13, 08)), local(2011, 02, 13)); - assert.deepEqual(floor(utc(2011, 02, 13, 09)), local(2011, 02, 13)); - assert.deepEqual(floor(utc(2011, 02, 13, 10)), local(2011, 02, 13)); - }, - "observes end of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 10, 06, 07)), local(2011, 10, 06)); - assert.deepEqual(floor(utc(2011, 10, 06, 08)), local(2011, 10, 06)); - assert.deepEqual(floor(utc(2011, 10, 06, 09)), local(2011, 10, 06)); - assert.deepEqual(floor(utc(2011, 10, 06, 10)), local(2011, 10, 06)); - }, - "correctly handles years in the first century": function(floor) { - assert.deepEqual(floor(local(0011, 10, 06, 07)), local(0011, 10, 06)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns midnights": function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 30, 23)), local(2010, 11, 31)); - assert.deepEqual(ceil(local(2010, 11, 31, 00)), local(2010, 11, 31)); - assert.deepEqual(ceil(local(2010, 11, 31, 01)), local(2011, 00, 01)); - }, - "observes start of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 02, 13, 07)), local(2011, 02, 13)); - assert.deepEqual(ceil(utc(2011, 02, 13, 08)), local(2011, 02, 13)); - assert.deepEqual(ceil(utc(2011, 02, 13, 09)), local(2011, 02, 14)); - assert.deepEqual(ceil(utc(2011, 02, 13, 10)), local(2011, 02, 14)); - }, - "observes end of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 10, 06, 07)), local(2011, 10, 06)); - assert.deepEqual(ceil(utc(2011, 10, 06, 08)), local(2011, 10, 07)); - assert.deepEqual(ceil(utc(2011, 10, 06, 09)), local(2011, 10, 07)); - assert.deepEqual(ceil(utc(2011, 10, 06, 10)), local(2011, 10, 07)); - }, - "handles midnight for leap years": function(ceil) { - assert.deepEqual(ceil(utc(2012, 02, 01, 00)), local(2012, 02, 01)); - assert.deepEqual(ceil(utc(2012, 02, 01, 00)), local(2012, 02, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = local(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, local(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), +1), local(2011, 00, 01, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 456), -2), local(2010, 11, 29, 23, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31), -1), local(2010, 11, 30)); - assert.deepEqual(offset(local(2011, 00, 01), -2), local(2010, 11, 30)); - assert.deepEqual(offset(local(2011, 00, 01), -1), local(2010, 11, 31)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31), +1), local(2011, 00, 01)); - assert.deepEqual(offset(local(2010, 11, 30), +2), local(2011, 00, 01)); - assert.deepEqual(offset(local(2010, 11, 30), +1), local(2010, 11, 31)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), 0), local(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58, 000), 0), local(2010, 11, 31, 23, 59, 58, 000)); - } - }, - "UTC": { - topic: function(interval) { - return interval.utc; - }, - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns midnights": function(floor) { - assert.deepEqual(floor(utc(2010, 11, 31, 23)), utc(2010, 11, 31)); - assert.deepEqual(floor(utc(2011, 00, 01, 00)), utc(2011, 00, 01)); - assert.deepEqual(floor(utc(2011, 00, 01, 01)), utc(2011, 00, 01)); - }, - "does not observe the start of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 02, 13, 07)), utc(2011, 02, 13)); - assert.deepEqual(floor(utc(2011, 02, 13, 08)), utc(2011, 02, 13)); - assert.deepEqual(floor(utc(2011, 02, 13, 09)), utc(2011, 02, 13)); - assert.deepEqual(floor(utc(2011, 02, 13, 10)), utc(2011, 02, 13)); - }, - "does not observe the end of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 10, 06, 05)), utc(2011, 10, 06)); - assert.deepEqual(floor(utc(2011, 10, 06, 06)), utc(2011, 10, 06)); - assert.deepEqual(floor(utc(2011, 10, 06, 07)), utc(2011, 10, 06)); - assert.deepEqual(floor(utc(2011, 10, 06, 08)), utc(2011, 10, 06)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns midnights": function(ceil) { - assert.deepEqual(ceil(utc(2010, 11, 30, 23)), utc(2010, 11, 31)); - assert.deepEqual(ceil(utc(2010, 11, 31, 00)), utc(2010, 11, 31)); - assert.deepEqual(ceil(utc(2010, 11, 31, 01)), utc(2011, 00, 01)); - }, - "does not observe the start of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 02, 13, 07)), utc(2011, 02, 14)); - assert.deepEqual(ceil(utc(2011, 02, 13, 08)), utc(2011, 02, 14)); - assert.deepEqual(ceil(utc(2011, 02, 13, 09)), utc(2011, 02, 14)); - assert.deepEqual(ceil(utc(2011, 02, 13, 10)), utc(2011, 02, 14)); - }, - "does not observe the end of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 10, 06, 05)), utc(2011, 10, 07)); - assert.deepEqual(ceil(utc(2011, 10, 06, 06)), utc(2011, 10, 07)); - assert.deepEqual(ceil(utc(2011, 10, 06, 07)), utc(2011, 10, 07)); - assert.deepEqual(ceil(utc(2011, 10, 06, 08)), utc(2011, 10, 07)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = utc(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, utc(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), +1), utc(2011, 00, 01, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 456), -2), utc(2010, 11, 29, 23, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31), -1), utc(2010, 11, 30)); - assert.deepEqual(offset(utc(2011, 00, 01), -2), utc(2010, 11, 30)); - assert.deepEqual(offset(utc(2011, 00, 01), -1), utc(2010, 11, 31)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31), +1), utc(2011, 00, 01)); - assert.deepEqual(offset(utc(2010, 11, 30), +2), utc(2011, 00, 01)); - assert.deepEqual(offset(utc(2010, 11, 30), +1), utc(2010, 11, 31)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), 0), utc(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58, 000), 0), utc(2010, 11, 31, 23, 59, 58, 000)); - } - } - } - } -}); - -suite.export(module); diff --git a/test/time/dayOfYear-test.js b/test/time/dayOfYear-test.js deleted file mode 100644 index 91866cd78e3886..00000000000000 --- a/test/time/dayOfYear-test.js +++ /dev/null @@ -1,16 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.time.dayOfYear"); - -suite.addBatch({ - "dayOfYear": { - topic: load("time/day").expression("d3.time.dayOfYear"), - "no floating-point rounding error": function(dayOfYear) { - assert.equal(dayOfYear(new Date(2011, 4, 9)), 128); - } - } -}); - -suite.export(module); diff --git a/test/time/days-test.js b/test/time/days-test.js deleted file mode 100644 index e20dc36c8209e8..00000000000000 --- a/test/time/days-test.js +++ /dev/null @@ -1,95 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.days"); - -suite.addBatch({ - "days": { - topic: load("time/day").expression("d3.time.days"), - "returns midnights": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 12), local(2011, 0, 3, 12)), [ - local(2011, 0, 1), - local(2011, 0, 2), - local(2011, 0, 3) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(local(2010, 11, 31), local(2011, 0, 3))[0], local(2010, 11, 31)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(local(2010, 11, 31), local(2011, 0, 3))[2], local(2011, 0, 2)); - }, - "can skip days": function(range) { - assert.deepEqual(range(local(2010, 11, 29), local(2011, 0, 14), 5), [ - local(2010, 11, 31), - local(2011, 0, 1), - local(2011, 0, 6), - local(2011, 0, 11) - ]); - }, - "observes start of daylight savings time": function(range) { - assert.deepEqual(range(local(2011, 2, 12), local(2011, 2, 16)), [ - local(2011, 2, 12), - local(2011, 2, 13), - local(2011, 2, 14), - local(2011, 2, 15) - ]); - }, - "observes end of daylight savings time": function(range) { - assert.deepEqual(range(local(2011, 10, 5), local(2011, 10, 9)), [ - local(2011, 10, 5), - local(2011, 10, 6), - local(2011, 10, 7), - local(2011, 10, 8) - ]); - }, - "UTC": { - topic: function(range) { - return range.utc; - }, - "returns midnights": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 12), utc(2011, 0, 3, 12)), [ - utc(2011, 0, 1), - utc(2011, 0, 2), - utc(2011, 0, 3) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 31), utc(2011, 0, 3))[0], utc(2010, 11, 31)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 31), utc(2011, 0, 3))[2], utc(2011, 0, 2)); - }, - "can skip days": function(range) { - assert.deepEqual(range(utc(2010, 11, 29), utc(2011, 0, 14), 5), [ - utc(2010, 11, 31), - utc(2011, 0, 1), - utc(2011, 0, 6), - utc(2011, 0, 11) - ]); - }, - "does not observe the start of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 2, 12), utc(2011, 2, 16)), [ - utc(2011, 2, 12), - utc(2011, 2, 13), - utc(2011, 2, 14), - utc(2011, 2, 15) - ]); - }, - "does not observe the end of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 10, 5), utc(2011, 10, 9)), [ - utc(2011, 10, 5), - utc(2011, 10, 6), - utc(2011, 10, 7), - utc(2011, 10, 8) - ]); - } - } - } -}); - -suite.export(module); diff --git a/test/time/format-iso-test.js b/test/time/format-iso-test.js deleted file mode 100644 index fbc0f91e42874a..00000000000000 --- a/test/time/format-iso-test.js +++ /dev/null @@ -1,33 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - utc = time.utc; - -var suite = vows.describe("d3.time.format"); - -suite.addBatch({ - "format.iso": { - topic: load("time/format-iso").expression("d3.time.format.iso"), - - "toString is %Y-%m-%dT%H:%M:%S.%LZ": function(format) { - assert.equal(format + "", "%Y-%m-%dT%H:%M:%S.%LZ"); - }, - - "formats as ISO 8601": function(format) { - assert.equal(format(utc(1990, 0, 1, 0, 0, 0)), "1990-01-01T00:00:00.000Z"); - assert.equal(format(utc(2011, 11, 31, 23, 59, 59)), "2011-12-31T23:59:59.000Z"); - }, - - "parse": { - "parses as ISO 8601": function(format) { - var p = format.parse; - assert.deepEqual(p("1990-01-01T00:00:00.000Z"), utc(1990, 0, 1, 0, 0, 0)); - assert.deepEqual(p("2011-12-31T23:59:59.000Z"), utc(2011, 11, 31, 23, 59, 59)); - assert.isNull(p("1990-01-01T00:00:00.000X")); - } - } - } -}); - -suite.export(module); diff --git a/test/time/format-test.js b/test/time/format-test.js deleted file mode 100644 index 6697d220c47c92..00000000000000 --- a/test/time/format-test.js +++ /dev/null @@ -1,310 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local; - -var suite = vows.describe("d3.time.format"); - -suite.addBatch({ - "format": { - topic: load("time/format").expression("d3.time.format"), - "formats abbreviated weekday": function(format) { - var f = format("%a"); - assert.equal(f(local(1990, 0, 1)), "Mon"); - assert.equal(f(local(1990, 0, 2)), "Tue"); - assert.equal(f(local(1990, 0, 3)), "Wed"); - assert.equal(f(local(1990, 0, 4)), "Thu"); - assert.equal(f(local(1990, 0, 5)), "Fri"); - assert.equal(f(local(1990, 0, 6)), "Sat"); - assert.equal(f(local(1990, 0, 7)), "Sun"); - }, - "formats weekday": function(format) { - var f = format("%A"); - assert.equal(f(local(1990, 0, 1)), "Monday"); - assert.equal(f(local(1990, 0, 2)), "Tuesday"); - assert.equal(f(local(1990, 0, 3)), "Wednesday"); - assert.equal(f(local(1990, 0, 4)), "Thursday"); - assert.equal(f(local(1990, 0, 5)), "Friday"); - assert.equal(f(local(1990, 0, 6)), "Saturday"); - assert.equal(f(local(1990, 0, 7)), "Sunday"); - }, - "formats abbreviated month": function(format) { - var f = format("%b"); - assert.equal(f(local(1990, 0, 1)), "Jan"); - assert.equal(f(local(1990, 1, 1)), "Feb"); - assert.equal(f(local(1990, 2, 1)), "Mar"); - assert.equal(f(local(1990, 3, 1)), "Apr"); - assert.equal(f(local(1990, 4, 1)), "May"); - assert.equal(f(local(1990, 5, 1)), "Jun"); - assert.equal(f(local(1990, 6, 1)), "Jul"); - assert.equal(f(local(1990, 7, 1)), "Aug"); - assert.equal(f(local(1990, 8, 1)), "Sep"); - assert.equal(f(local(1990, 9, 1)), "Oct"); - assert.equal(f(local(1990, 10, 1)), "Nov"); - assert.equal(f(local(1990, 11, 1)), "Dec"); - }, - "formats locale date and time": function(format) { - var f = format("%c"); - assert.equal(f(local(1990, 0, 1)), "Mon Jan 1 00:00:00 1990"); - }, - "formats zero-padded date": function(format) { - var f = format("%d"); - assert.equal(f(local(1990, 0, 1)), "01"); - }, - "formats space-padded date": function(format) { - var f = format("%e"); - assert.equal(f(local(1990, 0, 1)), " 1"); - }, - "formats zero-padded hour (24)": function(format) { - var f = format("%H"); - assert.equal(f(local(1990, 0, 1, 0)), "00"); - assert.equal(f(local(1990, 0, 1, 13)), "13"); - }, - "formats zero-padded hour (12)": function(format) { - var f = format("%I"); - assert.equal(f(local(1990, 0, 1, 0)), "12"); - assert.equal(f(local(1990, 0, 1, 13)), "01"); - }, - "formats zero-padded day of year": function(format) { - var f = format("%j"); - assert.equal(f(local(1990, 0, 1)), "001"); - assert.equal(f(local(1990, 5, 1)), "152"); - assert.equal(f(local(2010, 2, 13)), "072"); - assert.equal(f(local(2010, 2, 14)), "073"); // DST begins - assert.equal(f(local(2010, 2, 15)), "074"); - assert.equal(f(local(2010, 10, 6)), "310"); - assert.equal(f(local(2010, 10, 7)), "311"); // DST ends - assert.equal(f(local(2010, 10, 8)), "312"); - }, - "formats zero-padded month": function(format) { - var f = format("%m"); - assert.equal(f(local(1990, 0, 1)), "01"); - assert.equal(f(local(1990, 9, 1)), "10"); - }, - "formats zero-padded minute": function(format) { - var f = format("%M"); - assert.equal(f(local(1990, 0, 1, 0, 0)), "00"); - assert.equal(f(local(1990, 0, 1, 0, 32)), "32"); - }, - "formats AM or PM": function(format) { - var f = format("%p"); - assert.equal(f(local(1990, 0, 1, 0)), "AM"); - assert.equal(f(local(1990, 0, 1, 13)), "PM"); - }, - "formats zero-padded second": function(format) { - var f = format("%S"); - assert.equal(f(local(1990, 0, 1, 0, 0, 0)), "00"); - assert.equal(f(local(1990, 0, 1, 0, 0, 32)), "32"); - var f = format("%0S"); - assert.equal(f(local(1990, 0, 1, 0, 0, 0)), "00"); - assert.equal(f(local(1990, 0, 1, 0, 0, 32)), "32"); - }, - "formats space-padded second": function(format) { - var f = format("%_S"); - assert.equal(f(local(1990, 0, 1, 0, 0, 0)), " 0"); - assert.equal(f(local(1990, 0, 1, 0, 0, 3)), " 3"); - assert.equal(f(local(1990, 0, 1, 0, 0, 32)), "32"); - }, - "formats no-padded second": function(format) { - var f = format("%-S"); - assert.equal(f(local(1990, 0, 1, 0, 0, 0)), "0"); - assert.equal(f(local(1990, 0, 1, 0, 0, 3)), "3"); - assert.equal(f(local(1990, 0, 1, 0, 0, 32)), "32"); - }, - "formats zero-padded millisecond": function(format) { - var f = format("%L"); - assert.equal(f(local(1990, 0, 1, 0, 0, 0, 0)), "000"); - assert.equal(f(local(1990, 0, 1, 0, 0, 0, 432)), "432"); - }, - "formats zero-padded week number": function(format) { - var f = format("%U"); - assert.equal(f(local(1990, 0, 1)), "00"); - assert.equal(f(local(1990, 5, 1)), "21"); - assert.equal(f(local(2010, 2, 13, 23)), "10"); - assert.equal(f(local(2010, 2, 14, 00)), "11"); // DST begins - assert.equal(f(local(2010, 2, 15, 00)), "11"); - assert.equal(f(local(2010, 10, 6, 23)), "44"); - assert.equal(f(local(2010, 10, 7, 00)), "45"); // DST ends - assert.equal(f(local(2010, 10, 8, 00)), "45"); - }, - "formats locale date": function(format) { - var f = format("%x"); - assert.equal(f(local(1990, 0, 1)), "01/01/1990"); - assert.equal(f(local(2010, 5, 1)), "06/01/2010"); - }, - "formats locale time": function(format) { - var f = format("%X"); - assert.equal(f(local(1990, 0, 1)), "00:00:00"); - assert.equal(f(local(1990, 0, 1, 13, 34, 59)), "13:34:59"); - }, - "formats zero-padded two-digit year": function(format) { - var f = format("%y"); - assert.equal(f(local(1990, 0, 1)), "90"); - assert.equal(f(local(2002, 0, 1)), "02"); - assert.equal(f(local(-2, 0, 1)), "-02"); - }, - "formats zero-padded four-digit year": function(format) { - var f = format("%Y"); - assert.equal(f(local(123, 0, 1)), "0123"); - assert.equal(f(local(1990, 0, 1)), "1990"); - assert.equal(f(local(2002, 0, 1)), "2002"); - assert.equal(f(local(10002, 0, 1)), "0002"); - assert.equal(f(local(-2, 0, 1)), "-0002"); - }, - "formats time zone": function(format) { - var f = format("%Z"); - assert.equal(f(local(1990, 0, 1)), "-0800"); - }, - "formats literal percent sign": function(format) { - var f = format("%%"); - assert.equal(f(local(1990, 0, 1)), "%"); - }, - - "parse": { - "parses abbreviated weekday and numeric date": function(format) { - var p = format("%a %m/%d/%Y").parse; - assert.deepEqual(p("Sun 01/01/1990"), local(1990, 0, 1)); - assert.deepEqual(p("Wed 02/03/1991"), local(1991, 1, 3)); - assert.isNull(p("XXX 03/10/2010")); - }, - "parses weekday and numeric date": function(format) { - var p = format("%A %m/%d/%Y").parse; - assert.deepEqual(p("Sunday 01/01/1990"), local(1990, 0, 1)); - assert.deepEqual(p("Wednesday 02/03/1991"), local(1991, 1, 3)); - assert.isNull(p("Caturday 03/10/2010")); - }, - "parses abbreviated weekday, week number (Sunday) and year": function(format) { - var p = format("%a %U %Y").parse; - assert.deepEqual(p("Mon 00 1990"), local(1990, 0, 1)); - assert.deepEqual(p("Sun 05 1991"), local(1991, 1, 3)); - assert.deepEqual(p("Sun 01 1995"), local(1995, 0, 1)); - assert.isNull(p("XXX 03 2010")); - }, - "parses weekday, week number (Sunday) and year": function(format) { - var p = format("%A %U %Y").parse; - assert.deepEqual(p("Monday 00 1990"), local(1990, 0, 1)); - assert.deepEqual(p("Sunday 05 1991"), local(1991, 1, 3)); - assert.deepEqual(p("Sunday 01 1995"), local(1995, 0, 1)); - assert.isNull(p("Caturday 03 2010")); - }, - "parses numeric weekday, week number (Sunday) and year": function(format) { - var p = format("%w %U %Y").parse; - assert.deepEqual(p("1 00 1990"), local(1990, 0, 1)); - assert.deepEqual(p("0 05 1991"), local(1991, 1, 3)); - assert.deepEqual(p("0 01 1995"), local(1995, 0, 1)); - assert.isNull(p("X 03 2010")); - }, - "parses abbreviated weekday, week number (Monday) and year": function(format) { - var p = format("%a %W %Y").parse; - assert.deepEqual(p("Mon 01 1990"), local(1990, 0, 1)); - assert.deepEqual(p("Sun 04 1991"), local(1991, 1, 3)); - assert.deepEqual(p("Sun 00 1995"), local(1995, 0, 1)); - assert.isNull(p("XXX 03 2010")); - }, - "parses weekday, week number (Monday) and year": function(format) { - var p = format("%A %W %Y").parse; - assert.deepEqual(p("Monday 01 1990"), local(1990, 0, 1)); - assert.deepEqual(p("Sunday 04 1991"), local(1991, 1, 3)); - assert.deepEqual(p("Sunday 00 1995"), local(1995, 0, 1)); - assert.isNull(p("Caturday 03 2010")); - }, - "parses numeric weekday, week number (Monday) and year": function(format) { - var p = format("%w %W %Y").parse; - assert.deepEqual(p("1 01 1990"), local(1990, 0, 1)); - assert.deepEqual(p("0 04 1991"), local(1991, 1, 3)); - assert.deepEqual(p("0 00 1995"), local(1995, 0, 1)); - assert.isNull(p("X 03 2010")); - }, - "parses numeric date": function(format) { - var p = format("%m/%d/%y").parse; - assert.deepEqual(p("01/01/90"), local(1990, 0, 1)); - assert.deepEqual(p("02/03/91"), local(1991, 1, 3)); - assert.isNull(p("03/10/2010")); - }, - "parses locale date": function(format) { - var p = format("%x").parse; - assert.deepEqual(p("01/01/1990"), local(1990, 0, 1)); - assert.deepEqual(p("02/03/1991"), local(1991, 1, 3)); - assert.deepEqual(p("03/10/2010"), local(2010, 2, 10)); - }, - "parses abbreviated month, date and year": function(format) { - var p = format("%b %d, %Y").parse; - assert.deepEqual(p("jan 01, 1990"), local(1990, 0, 1)); - assert.deepEqual(p("feb 2, 2010"), local(2010, 1, 2)); - assert.isNull(p("jan. 1, 1990")); - }, - "parses month, date and year": function(format) { - var p = format("%B %d, %Y").parse; - assert.deepEqual(p("january 01, 1990"), local(1990, 0, 1)); - assert.deepEqual(p("February 2, 2010"), local(2010, 1, 2)); - assert.isNull(p("jan 1, 1990")); - }, - "parses day of year and numeric date": function(format) { - var p = format("%j %m/%d/%Y").parse; - assert.deepEqual(p("001 01/01/1990"), local(1990, 0, 1)); - assert.deepEqual(p("034 02/03/1991"), local(1991, 1, 3)); - assert.isNull(p("2012 03/10/2010")); - }, - "parses locale date and time": function(format) { - var p = format("%c").parse; - assert.deepEqual(p("Mon Jan 1 00:00:00 1990"), local(1990, 0, 1)); - assert.deepEqual(p("Sun Jan 1 00:00:00 1990"), local(1990, 0, 1)); - assert.deepEqual(p("Mon Jan 01 00:00:00 1990"), local(1990, 0, 1)); - assert.deepEqual(p("Mon Jan 1 00:00:00 1990"), local(1990, 0, 1)); - assert.deepEqual(p("Mon Jan 1 0:0:0 1990"), local(1990, 0, 1)); - }, - "parses twenty-four hour, minute and second": function(format) { - var p = format("%H:%M:%S").parse; - assert.deepEqual(p("00:00:00"), local(1900, 0, 1, 0, 0, 0)); - assert.deepEqual(p("11:59:59"), local(1900, 0, 1, 11, 59, 59)); - assert.deepEqual(p("12:00:00"), local(1900, 0, 1, 12, 0, 0)); - assert.deepEqual(p("12:00:01"), local(1900, 0, 1, 12, 0, 1)); - assert.deepEqual(p("23:59:59"), local(1900, 0, 1, 23, 59, 59)); - }, - "parses locale time": function(format) { - var p = format("%X").parse; - assert.deepEqual(p("00:00:00"), local(1900, 0, 1, 0, 0, 0)); - assert.deepEqual(p("11:59:59"), local(1900, 0, 1, 11, 59, 59)); - assert.deepEqual(p("12:00:00"), local(1900, 0, 1, 12, 0, 0)); - assert.deepEqual(p("12:00:01"), local(1900, 0, 1, 12, 0, 1)); - assert.deepEqual(p("23:59:59"), local(1900, 0, 1, 23, 59, 59)); - }, - "parses twelve hour, minute and second": function(format) { - var p = format("%I:%M:%S %p").parse; - assert.deepEqual(p("12:00:00 am"), local(1900, 0, 1, 0, 0, 0)); - assert.deepEqual(p("11:59:59 AM"), local(1900, 0, 1, 11, 59, 59)); - assert.deepEqual(p("12:00:00 pm"), local(1900, 0, 1, 12, 0, 0)); - assert.deepEqual(p("12:00:01 pm"), local(1900, 0, 1, 12, 0, 1)); - assert.deepEqual(p("11:59:59 PM"), local(1900, 0, 1, 23, 59, 59)); - }, - "parses literal %": function(format) { - var p = format("%% %m/%d/%Y").parse; - assert.deepEqual(p("% 01/01/1990"), local(1990, 0, 1)); - assert.deepEqual(p("% 02/03/1991"), local(1991, 1, 3)); - assert.isNull(p("%% 03/10/2010")); - }, - "parses timezone offset": function(format) { - var p = format("%m/%d/%Y %Z").parse; - assert.deepEqual(p("01/02/1990 +0000"), local(1990, 0, 1, 16)); - assert.deepEqual(p("01/02/1990 +0100"), local(1990, 0, 1, 17)); - assert.deepEqual(p("01/02/1990 -0100"), local(1990, 0, 1, 15)); - }, - "ignores optional padding modifier, skipping zeroes and spaces": function(format) { - var p = format("%-m/%0d/%_Y").parse; - assert.deepEqual(p("01/ 1/1990"), local(1990, 0, 1)); - }, - "doesn't crash when given weird strings": function(format) { - try { - Object.prototype.foo = 10; - var p = format("%b %d, %Y").parse; - assert.isNull(p("foo 1, 1990")); - } finally { - delete Object.prototype.foo; - } - } - } - } -}); - -suite.export(module); diff --git a/test/time/format-utc-test.js b/test/time/format-utc-test.js deleted file mode 100644 index a42a895c25aa6a..00000000000000 --- a/test/time/format-utc-test.js +++ /dev/null @@ -1,225 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - utc = time.utc; - -var suite = vows.describe("d3.time.format"); - -suite.addBatch({ - "format.utc": { - topic: load("time/format-utc").expression("d3.time.format.utc"), - "formats abbreviated weekday": function(format) { - var f = format("%a"); - assert.equal(f(utc(1990, 0, 1)), "Mon"); - assert.equal(f(utc(1990, 0, 2)), "Tue"); - assert.equal(f(utc(1990, 0, 3)), "Wed"); - assert.equal(f(utc(1990, 0, 4)), "Thu"); - assert.equal(f(utc(1990, 0, 5)), "Fri"); - assert.equal(f(utc(1990, 0, 6)), "Sat"); - assert.equal(f(utc(1990, 0, 7)), "Sun"); - }, - "formats weekday": function(format) { - var f = format("%A"); - assert.equal(f(utc(1990, 0, 1)), "Monday"); - assert.equal(f(utc(1990, 0, 2)), "Tuesday"); - assert.equal(f(utc(1990, 0, 3)), "Wednesday"); - assert.equal(f(utc(1990, 0, 4)), "Thursday"); - assert.equal(f(utc(1990, 0, 5)), "Friday"); - assert.equal(f(utc(1990, 0, 6)), "Saturday"); - assert.equal(f(utc(1990, 0, 7)), "Sunday"); - }, - "formats abbreviated month": function(format) { - var f = format("%b"); - assert.equal(f(utc(1990, 0, 1)), "Jan"); - assert.equal(f(utc(1990, 1, 1)), "Feb"); - assert.equal(f(utc(1990, 2, 1)), "Mar"); - assert.equal(f(utc(1990, 3, 1)), "Apr"); - assert.equal(f(utc(1990, 4, 1)), "May"); - assert.equal(f(utc(1990, 5, 1)), "Jun"); - assert.equal(f(utc(1990, 6, 1)), "Jul"); - assert.equal(f(utc(1990, 7, 1)), "Aug"); - assert.equal(f(utc(1990, 8, 1)), "Sep"); - assert.equal(f(utc(1990, 9, 1)), "Oct"); - assert.equal(f(utc(1990, 10, 1)), "Nov"); - assert.equal(f(utc(1990, 11, 1)), "Dec"); - }, - "formats locale date and time": function(format) { - var f = format("%c"); - assert.equal(f(utc(1990, 0, 1)), "Mon Jan 1 00:00:00 1990"); - }, - "formats zero-padded date": function(format) { - var f = format("%d"); - assert.equal(f(utc(1990, 0, 1)), "01"); - }, - "formats space-padded date": function(format) { - var f = format("%e"); - assert.equal(f(utc(1990, 0, 1)), " 1"); - }, - "formats zero-padded hour (24)": function(format) { - var f = format("%H"); - assert.equal(f(utc(1990, 0, 1, 0)), "00"); - assert.equal(f(utc(1990, 0, 1, 13)), "13"); - }, - "formats zero-padded hour (12)": function(format) { - var f = format("%I"); - assert.equal(f(utc(1990, 0, 1, 0)), "12"); - assert.equal(f(utc(1990, 0, 1, 13)), "01"); - }, - "formats zero-padded day of year": function(format) { - var f = format("%j"); - assert.equal(f(utc(1990, 0, 1)), "001"); - assert.equal(f(utc(1990, 5, 1)), "152"); - assert.equal(f(utc(2010, 2, 13, 23)), "072"); - assert.equal(f(utc(2010, 2, 14, 00)), "073"); // DST begins - assert.equal(f(utc(2010, 2, 15, 00)), "074"); - assert.equal(f(utc(2010, 10, 6, 23)), "310"); - assert.equal(f(utc(2010, 10, 7, 00)), "311"); // DST ends - assert.equal(f(utc(2010, 10, 8, 00)), "312"); - }, - "formats zero-padded month": function(format) { - var f = format("%m"); - assert.equal(f(utc(1990, 0, 1)), "01"); - assert.equal(f(utc(1990, 9, 1)), "10"); - }, - "formats zero-padded minute": function(format) { - var f = format("%M"); - assert.equal(f(utc(1990, 0, 1, 0, 0)), "00"); - assert.equal(f(utc(1990, 0, 1, 0, 32)), "32"); - }, - "formats AM or PM": function(format) { - var f = format("%p"); - assert.equal(f(utc(1990, 0, 1, 0)), "AM"); - assert.equal(f(utc(1990, 0, 1, 13)), "PM"); - }, - "formats zero-padded second": function(format) { - var f = format("%S"); - assert.equal(f(utc(1990, 0, 1, 0, 0, 0)), "00"); - assert.equal(f(utc(1990, 0, 1, 0, 0, 32)), "32"); - }, - "formats zero-padded millisecond": function(format) { - var f = format("%L"); - assert.equal(f(utc(1990, 0, 1, 0, 0, 0, 0)), "000"); - assert.equal(f(utc(1990, 0, 1, 0, 0, 0, 432)), "432"); - }, - "formats zero-padded week number": function(format) { - var f = format("%U"); - assert.equal(f(utc(1990, 0, 1)), "00"); - assert.equal(f(utc(1990, 5, 1)), "21"); - assert.equal(f(utc(2010, 2, 13, 23)), "10"); - assert.equal(f(utc(2010, 2, 14, 00)), "11"); // DST begins - assert.equal(f(utc(2010, 2, 15, 00)), "11"); - assert.equal(f(utc(2010, 10, 6, 23)), "44"); - assert.equal(f(utc(2010, 10, 7, 00)), "45"); // DST ends - assert.equal(f(utc(2010, 10, 8, 00)), "45"); - }, - "formats locale date": function(format) { - var f = format("%x"); - assert.equal(f(utc(1990, 0, 1)), "01/01/1990"); - assert.equal(f(utc(2010, 5, 1)), "06/01/2010"); - }, - "formats locale time": function(format) { - var f = format("%X"); - assert.equal(f(utc(1990, 0, 1)), "00:00:00"); - assert.equal(f(utc(1990, 0, 1, 13, 34, 59)), "13:34:59"); - }, - "formats zero-padded two-digit year": function(format) { - var f = format("%y"); - assert.equal(f(utc(1990, 0, 1)), "90"); - assert.equal(f(utc(2002, 0, 1)), "02"); - }, - "formats zero-padded four-digit year": function(format) { - var f = format("%Y"); - assert.equal(f(utc(123, 0, 1)), "0123"); - assert.equal(f(utc(1990, 0, 1)), "1990"); - assert.equal(f(utc(2002, 0, 1)), "2002"); - assert.equal(f(utc(10002, 0, 1)), "0002"); - }, - "formats time zone": function(format) { - var f = format("%Z"); - assert.equal(f(utc(1990, 0, 1)), "+0000"); - }, - "formats literal percent sign": function(format) { - var f = format("%%"); - assert.equal(f(utc(1990, 0, 1)), "%"); - }, - "parse": { - "parses abbreviated weekday and numeric date": function(format) { - var p = format("%a %m/%d/%Y").parse; - assert.deepEqual(p("Sun 01/01/1990"), utc(1990, 0, 1)); - assert.deepEqual(p("Wed 02/03/1991"), utc(1991, 1, 3)); - assert.isNull(p("XXX 03/10/2010")); - }, - "parses weekday and numeric date": function(format) { - var p = format("%A %m/%d/%Y").parse; - assert.deepEqual(p("Sunday 01/01/1990"), utc(1990, 0, 1)); - assert.deepEqual(p("Wednesday 02/03/1991"), utc(1991, 1, 3)); - assert.isNull(p("Caturday 03/10/2010")); - }, - "parses numeric date": function(format) { - var p = format("%m/%d/%y").parse; - assert.deepEqual(p("01/01/90"), utc(1990, 0, 1)); - assert.deepEqual(p("02/03/91"), utc(1991, 1, 3)); - assert.isNull(p("03/10/2010")); - }, - "parses locale date": function(format) { - var p = format("%x").parse; - assert.deepEqual(p("01/01/1990"), utc(1990, 0, 1)); - assert.deepEqual(p("02/03/1991"), utc(1991, 1, 3)); - assert.deepEqual(p("03/10/2010"), utc(2010, 2, 10)); - }, - "parses abbreviated month, date and year": function(format) { - var p = format("%b %d, %Y").parse; - assert.deepEqual(p("jan 01, 1990"), utc(1990, 0, 1)); - assert.deepEqual(p("feb 2, 2010"), utc(2010, 1, 2)); - assert.isNull(p("jan. 1, 1990")); - }, - "parses month, date and year": function(format) { - var p = format("%B %d, %Y").parse; - assert.deepEqual(p("january 01, 1990"), utc(1990, 0, 1)); - assert.deepEqual(p("February 2, 2010"), utc(2010, 1, 2)); - assert.isNull(p("jan 1, 1990")); - }, - "parses locale date and time": function(format) { - var p = format("%c").parse; - assert.deepEqual(p("Mon Jan 1 00:00:00 1990"), utc(1990, 0, 1)); - assert.deepEqual(p("Sun Jan 1 00:00:00 1990"), utc(1990, 0, 1)); - assert.deepEqual(p("Mon Jan 01 00:00:00 1990"), utc(1990, 0, 1)); - assert.deepEqual(p("Mon Jan 1 00:00:00 1990"), utc(1990, 0, 1)); - assert.deepEqual(p("Mon Jan 1 0:0:0 1990"), utc(1990, 0, 1)); - }, - "parses twenty-four hour, minute and second": function(format) { - var p = format("%H:%M:%S").parse; - assert.deepEqual(p("00:00:00"), utc(1900, 0, 1, 0, 0, 0)); - assert.deepEqual(p("11:59:59"), utc(1900, 0, 1, 11, 59, 59)); - assert.deepEqual(p("12:00:00"), utc(1900, 0, 1, 12, 0, 0)); - assert.deepEqual(p("12:00:01"), utc(1900, 0, 1, 12, 0, 1)); - assert.deepEqual(p("23:59:59"), utc(1900, 0, 1, 23, 59, 59)); - }, - "parses locale time": function(format) { - var p = format("%X").parse; - assert.deepEqual(p("00:00:00"), utc(1900, 0, 1, 0, 0, 0)); - assert.deepEqual(p("11:59:59"), utc(1900, 0, 1, 11, 59, 59)); - assert.deepEqual(p("12:00:00"), utc(1900, 0, 1, 12, 0, 0)); - assert.deepEqual(p("12:00:01"), utc(1900, 0, 1, 12, 0, 1)); - assert.deepEqual(p("23:59:59"), utc(1900, 0, 1, 23, 59, 59)); - }, - "parses twelve hour, minute and second": function(format) { - var p = format("%I:%M:%S %p").parse; - assert.deepEqual(p("12:00:00 am"), utc(1900, 0, 1, 0, 0, 0)); - assert.deepEqual(p("11:59:59 AM"), utc(1900, 0, 1, 11, 59, 59)); - assert.deepEqual(p("12:00:00 pm"), utc(1900, 0, 1, 12, 0, 0)); - assert.deepEqual(p("12:00:01 pm"), utc(1900, 0, 1, 12, 0, 1)); - assert.deepEqual(p("11:59:59 PM"), utc(1900, 0, 1, 23, 59, 59)); - }, - "parses timezone offset": function(format) { - var p = format("%m/%d/%Y %Z").parse; - assert.deepEqual(p("01/02/1990 +0000"), utc(1990, 0, 2)); - assert.deepEqual(p("01/02/1990 +0100"), utc(1990, 0, 2, 1)); - assert.deepEqual(p("01/02/1990 -0100"), utc(1990, 0, 1, 23)); - } - } - } -}); - -suite.export(module); diff --git a/test/time/hour-test.js b/test/time/hour-test.js deleted file mode 100644 index 757ae2267f9536..00000000000000 --- a/test/time/hour-test.js +++ /dev/null @@ -1,215 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.hour"); - -suite.addBatch({ - "hour": { - topic: load("time/hour").expression("d3.time.hour"), - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns hours": function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23, 59)), local(2010, 11, 31, 23)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00)), local(2011, 00, 01, 00)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 01)), local(2011, 00, 01, 00)); - }, - "observes start of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 02, 13, 08, 59)), utc(2011, 02, 13, 08)); - assert.deepEqual(floor(utc(2011, 02, 13, 09, 00)), utc(2011, 02, 13, 09)); - assert.deepEqual(floor(utc(2011, 02, 13, 09, 01)), utc(2011, 02, 13, 09)); - assert.deepEqual(floor(utc(2011, 02, 13, 09, 59)), utc(2011, 02, 13, 09)); - assert.deepEqual(floor(utc(2011, 02, 13, 10, 00)), utc(2011, 02, 13, 10)); - assert.deepEqual(floor(utc(2011, 02, 13, 10, 01)), utc(2011, 02, 13, 10)); - }, - "observes end of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 10, 06, 07, 59)), utc(2011, 10, 06, 07)); - assert.deepEqual(floor(utc(2011, 10, 06, 08, 00)), utc(2011, 10, 06, 08)); - assert.deepEqual(floor(utc(2011, 10, 06, 08, 01)), utc(2011, 10, 06, 08)); - assert.deepEqual(floor(utc(2011, 10, 06, 08, 59)), utc(2011, 10, 06, 08)); - assert.deepEqual(floor(utc(2011, 10, 06, 09, 00)), utc(2011, 10, 06, 09)); - assert.deepEqual(floor(utc(2011, 10, 06, 09, 01)), utc(2011, 10, 06, 09)); - }, - "NPT": { - "observes 15-minute offset": time.zone(345, function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23, 59, 59)), utc(2010, 11, 31, 17, 15)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 00)), utc(2010, 11, 31, 18, 15)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 01)), utc(2010, 11, 31, 18, 15)); - }) - }, - "IST": { - "observes 30-minute offset": time.zone(330, function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23, 59, 59)), utc(2010, 11, 31, 17, 30)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 00)), utc(2010, 11, 31, 18, 30)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 01)), utc(2010, 11, 31, 18, 30)); - }) - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns hours": function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 31, 23, 59)), local(2011, 00, 01, 00)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00)), local(2011, 00, 01, 00)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 01)), local(2011, 00, 01, 01)); - }, - "observes start of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 02, 13, 08, 59)), utc(2011, 02, 13, 09)); - assert.deepEqual(ceil(utc(2011, 02, 13, 09, 00)), utc(2011, 02, 13, 09)); - assert.deepEqual(ceil(utc(2011, 02, 13, 09, 01)), utc(2011, 02, 13, 10)); - assert.deepEqual(ceil(utc(2011, 02, 13, 09, 59)), utc(2011, 02, 13, 10)); - assert.deepEqual(ceil(utc(2011, 02, 13, 10, 00)), utc(2011, 02, 13, 10)); - assert.deepEqual(ceil(utc(2011, 02, 13, 10, 01)), utc(2011, 02, 13, 11)); - }, - "observes end of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 10, 06, 07, 59)), utc(2011, 10, 06, 08)); - assert.deepEqual(ceil(utc(2011, 10, 06, 08, 00)), utc(2011, 10, 06, 08)); - assert.deepEqual(ceil(utc(2011, 10, 06, 08, 01)), utc(2011, 10, 06, 09)); - assert.deepEqual(ceil(utc(2011, 10, 06, 08, 59)), utc(2011, 10, 06, 09)); - assert.deepEqual(ceil(utc(2011, 10, 06, 09, 00)), utc(2011, 10, 06, 09)); - assert.deepEqual(ceil(utc(2011, 10, 06, 09, 01)), utc(2011, 10, 06, 10)); - }, - "NPT": { - "observes 15-minute offset": time.zone(345, function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 31, 23, 59, 59)), utc(2010, 11, 31, 18, 15)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 00)), utc(2010, 11, 31, 18, 15)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 01)), utc(2010, 11, 31, 19, 15)); - }) - }, - "IST": { - "observes 30-minute offset": time.zone(330, function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 31, 23, 59, 59)), utc(2010, 11, 31, 18, 30)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 00)), utc(2010, 11, 31, 18, 30)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 01)), utc(2010, 11, 31, 19, 30)); - }) - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = local(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, local(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), +1), local(2011, 00, 01, 00, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 456), -2), local(2010, 11, 31, 21, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 12), -1), local(2010, 11, 31, 11)); - assert.deepEqual(offset(local(2011, 00, 01, 01), -2), local(2010, 11, 31, 23)); - assert.deepEqual(offset(local(2011, 00, 01, 00), -1), local(2010, 11, 31, 23)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 11), +1), local(2010, 11, 31, 12)); - assert.deepEqual(offset(local(2010, 11, 31, 23), +2), local(2011, 00, 01, 01)); - assert.deepEqual(offset(local(2010, 11, 31, 23), +1), local(2011, 00, 01, 00)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), 0), local(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58, 000), 0), local(2010, 11, 31, 23, 59, 58, 000)); - } - }, - "UTC": { - topic: function(interval) { - return interval.utc; - }, - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns hours": function(floor) { - assert.deepEqual(floor(utc(2010, 11, 31, 23, 59)), utc(2010, 11, 31, 23)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00)), utc(2011, 00, 01, 00)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 01)), utc(2011, 00, 01, 00)); - }, - "does not observe the start of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 02, 13, 08, 59)), utc(2011, 02, 13, 08)); - assert.deepEqual(floor(utc(2011, 02, 13, 09, 00)), utc(2011, 02, 13, 09)); - assert.deepEqual(floor(utc(2011, 02, 13, 09, 01)), utc(2011, 02, 13, 09)); - assert.deepEqual(floor(utc(2011, 02, 13, 09, 59)), utc(2011, 02, 13, 09)); - assert.deepEqual(floor(utc(2011, 02, 13, 10, 00)), utc(2011, 02, 13, 10)); - assert.deepEqual(floor(utc(2011, 02, 13, 10, 01)), utc(2011, 02, 13, 10)); - }, - "does not observe the end of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 10, 06, 07, 59)), utc(2011, 10, 06, 07)); - assert.deepEqual(floor(utc(2011, 10, 06, 08, 00)), utc(2011, 10, 06, 08)); - assert.deepEqual(floor(utc(2011, 10, 06, 08, 01)), utc(2011, 10, 06, 08)); - assert.deepEqual(floor(utc(2011, 10, 06, 08, 59)), utc(2011, 10, 06, 08)); - assert.deepEqual(floor(utc(2011, 10, 06, 09, 00)), utc(2011, 10, 06, 09)); - assert.deepEqual(floor(utc(2011, 10, 06, 09, 01)), utc(2011, 10, 06, 09)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns hours": function(ceil) { - assert.deepEqual(ceil(utc(2010, 11, 31, 23, 59)), utc(2011, 00, 01, 00)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00)), utc(2011, 00, 01, 00)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 01)), utc(2011, 00, 01, 01)); - }, - "does not observe the start of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 02, 13, 08, 59)), utc(2011, 02, 13, 09)); - assert.deepEqual(ceil(utc(2011, 02, 13, 09, 00)), utc(2011, 02, 13, 09)); - assert.deepEqual(ceil(utc(2011, 02, 13, 09, 01)), utc(2011, 02, 13, 10)); - assert.deepEqual(ceil(utc(2011, 02, 13, 09, 59)), utc(2011, 02, 13, 10)); - assert.deepEqual(ceil(utc(2011, 02, 13, 10, 00)), utc(2011, 02, 13, 10)); - assert.deepEqual(ceil(utc(2011, 02, 13, 10, 01)), utc(2011, 02, 13, 11)); - }, - "does not observe the end of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 10, 06, 07, 59)), utc(2011, 10, 06, 08)); - assert.deepEqual(ceil(utc(2011, 10, 06, 08, 00)), utc(2011, 10, 06, 08)); - assert.deepEqual(ceil(utc(2011, 10, 06, 08, 01)), utc(2011, 10, 06, 09)); - assert.deepEqual(ceil(utc(2011, 10, 06, 08, 59)), utc(2011, 10, 06, 09)); - assert.deepEqual(ceil(utc(2011, 10, 06, 09, 00)), utc(2011, 10, 06, 09)); - assert.deepEqual(ceil(utc(2011, 10, 06, 09, 01)), utc(2011, 10, 06, 10)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = utc(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, utc(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), +1), utc(2011, 00, 01, 00, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 456), -2), utc(2010, 11, 31, 21, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 12), -1), utc(2010, 11, 31, 11)); - assert.deepEqual(offset(utc(2011, 00, 01, 01), -2), utc(2010, 11, 31, 23)); - assert.deepEqual(offset(utc(2011, 00, 01, 00), -1), utc(2010, 11, 31, 23)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 11), +1), utc(2010, 11, 31, 12)); - assert.deepEqual(offset(utc(2010, 11, 31, 23), +2), utc(2011, 00, 01, 01)); - assert.deepEqual(offset(utc(2010, 11, 31, 23), +1), utc(2011, 00, 01, 00)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), 0), utc(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58, 000), 0), utc(2010, 11, 31, 23, 59, 58, 000)); - } - } - } - } -}); - -suite.export(module); diff --git a/test/time/hours-test.js b/test/time/hours-test.js deleted file mode 100644 index c0a6a767cde3b5..00000000000000 --- a/test/time/hours-test.js +++ /dev/null @@ -1,109 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.hours"); - -suite.addBatch({ - "hours": { - topic: load("time/hour").expression("d3.time.hours"), - "returns hours": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 12, 30), local(2010, 11, 31, 15, 30)), [ - local(2010, 11, 31, 13), - local(2010, 11, 31, 14), - local(2010, 11, 31, 15) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 23), local(2011, 0, 1, 2))[0], local(2010, 11, 31, 23)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 23), local(2011, 0, 1, 2))[2], local(2011, 0, 1, 1)); - }, - "can skip hours": function(range) { - assert.deepEqual(range(local(2011, 1, 1, 1), local(2011, 1, 1, 13), 3), [ - local(2011, 1, 1, 3), - local(2011, 1, 1, 6), - local(2011, 1, 1, 9), - local(2011, 1, 1, 12) - ]); - }, - "observes start of daylight savings time": function(range) { - assert.deepEqual(range(local(2011, 2, 13, 1), local(2011, 2, 13, 5)), [ - utc(2011, 2, 13, 9), - utc(2011, 2, 13, 10), - utc(2011, 2, 13, 11) - ]); - }, - "observes end of daylight savings time": function(range) { - assert.deepEqual(range(local(2011, 10, 6, 0), local(2011, 10, 6, 2)), [ - utc(2011, 10, 6, 7), - utc(2011, 10, 6, 8), - utc(2011, 10, 6, 9) - ]); - }, - "NPT": { - "observes 15-minute offset": time.zone(345, function(range) { - assert.deepEqual(range(local(2011, 10, 7, 0), local(2011, 10, 7, 3)), [ - utc(2011, 10, 6, 18, 15), - utc(2011, 10, 6, 19, 15), - utc(2011, 10, 6, 20, 15) - ]); - }) - }, - "IST": { - "observes 30-minute offset": time.zone(330, function(range) { - assert.deepEqual(range(local(2011, 10, 7, 0), local(2011, 10, 7, 3)), [ - utc(2011, 10, 6, 18, 30), - utc(2011, 10, 6, 19, 30), - utc(2011, 10, 6, 20, 30) - ]); - }) - }, - "UTC": { - topic: function(range) { - return range.utc; - }, - "returns hours": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 12, 30), utc(2010, 11, 31, 15, 30)), [ - utc(2010, 11, 31, 13), - utc(2010, 11, 31, 14), - utc(2010, 11, 31, 15) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 23), utc(2011, 0, 1, 2))[0], utc(2010, 11, 31, 23)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 23), utc(2011, 0, 1, 2))[2], utc(2011, 0, 1, 1)); - }, - "can skip hours": function(range) { - assert.deepEqual(range(utc(2011, 1, 1, 1), utc(2011, 1, 1, 13), 3), [ - utc(2011, 1, 1, 3), - utc(2011, 1, 1, 6), - utc(2011, 1, 1, 9), - utc(2011, 1, 1, 12) - ]); - }, - "observes start of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 2, 13, 9), utc(2011, 2, 13, 12)), [ - utc(2011, 2, 13, 9), - utc(2011, 2, 13, 10), - utc(2011, 2, 13, 11) - ]); - }, - "observes end of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 10, 6, 7), utc(2011, 10, 6, 10)), [ - utc(2011, 10, 6, 7), - utc(2011, 10, 6, 8), - utc(2011, 10, 6, 9) - ]); - } - } - } -}); - -suite.export(module); diff --git a/test/time/minute-test.js b/test/time/minute-test.js deleted file mode 100644 index e3a3c3c2c0608f..00000000000000 --- a/test/time/minute-test.js +++ /dev/null @@ -1,127 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.minute"); - -suite.addBatch({ - "minute": { - topic: load("time/minute").expression("d3.time.minute"), - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns minutes": function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23, 59, 59)), local(2010, 11, 31, 23, 59)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 00)), local(2011, 00, 01, 00, 00)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 59)), local(2011, 00, 01, 00, 00)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 01, 00)), local(2011, 00, 01, 00, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns minutes": function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 31, 23, 59, 59)), local(2011, 00, 01, 00, 00)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 00)), local(2011, 00, 01, 00, 00)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 59)), local(2011, 00, 01, 00, 01)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 01, 00)), local(2011, 00, 01, 00, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = local(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, local(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), +1), local(2011, 00, 01, 00, 00, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 456), -2), local(2010, 11, 31, 23, 57, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 12), -1), local(2010, 11, 31, 23, 11)); - assert.deepEqual(offset(local(2011, 00, 01, 00, 01), -2), local(2010, 11, 31, 23, 59)); - assert.deepEqual(offset(local(2011, 00, 01, 00, 00), -1), local(2010, 11, 31, 23, 59)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 11), +1), local(2010, 11, 31, 23, 12)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59), +2), local(2011, 00, 01, 00, 01)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59), +1), local(2011, 00, 01, 00, 00)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), 0), local(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58, 000), 0), local(2010, 11, 31, 23, 59, 58, 000)); - } - }, - "UTC": { - topic: function(interval) { - return interval.utc; - }, - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns minutes": function(floor) { - assert.deepEqual(floor(utc(2010, 11, 31, 23, 59, 59)), utc(2010, 11, 31, 23, 59)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 00)), utc(2011, 00, 01, 00, 00)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 59)), utc(2011, 00, 01, 00, 00)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 01, 00)), utc(2011, 00, 01, 00, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns minutes": function(ceil) { - assert.deepEqual(ceil(utc(2010, 11, 31, 23, 59, 59)), utc(2011, 00, 01, 00, 00)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 00)), utc(2011, 00, 01, 00, 00)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 59)), utc(2011, 00, 01, 00, 01)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 01, 00)), utc(2011, 00, 01, 00, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = utc(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, utc(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), +1), utc(2011, 00, 01, 00, 00, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 456), -2), utc(2010, 11, 31, 23, 57, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 12), -1), utc(2010, 11, 31, 23, 11)); - assert.deepEqual(offset(utc(2011, 00, 01, 00, 01), -2), utc(2010, 11, 31, 23, 59)); - assert.deepEqual(offset(utc(2011, 00, 01, 00, 00), -1), utc(2010, 11, 31, 23, 59)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 11), +1), utc(2010, 11, 31, 23, 12)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59), +2), utc(2011, 00, 01, 00, 01)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59), +1), utc(2011, 00, 01, 00, 00)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), 0), utc(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58, 000), 0), utc(2010, 11, 31, 23, 59, 58, 000)); - } - } - } - } -}); - -suite.export(module); diff --git a/test/time/minutes-test.js b/test/time/minutes-test.js deleted file mode 100644 index 1d176bfcd37952..00000000000000 --- a/test/time/minutes-test.js +++ /dev/null @@ -1,91 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.minutes"); - -suite.addBatch({ - "minutes": { - topic: load("time/minute").expression("d3.time.minutes"), - "returns minutes": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 23, 59), local(2011, 0, 1, 0, 2)), [ - local(2010, 11, 31, 23, 59), - local(2011, 0, 1, 0, 0), - local(2011, 0, 1, 0, 1) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 23, 59), local(2011, 0, 1, 0, 2))[0], local(2010, 11, 31, 23, 59)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 23, 59), local(2011, 0, 1, 0, 2))[2], local(2011, 0, 1, 0, 1)); - }, - "can skip minutes": function(range) { - assert.deepEqual(range(local(2011, 1, 1, 12, 7), local(2011, 1, 1, 13, 7), 15), [ - local(2011, 1, 1, 12, 15), - local(2011, 1, 1, 12, 30), - local(2011, 1, 1, 12, 45), - local(2011, 1, 1, 13, 0) - ]); - }, - "observes start of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 2, 13, 9, 59), utc(2011, 2, 13, 10, 2)), [ - utc(2011, 2, 13, 9, 59), - utc(2011, 2, 13, 10, 0), - utc(2011, 2, 13, 10, 1) - ]); - }, - "observes end of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 10, 6, 8, 59), utc(2011, 10, 6, 9, 2)), [ - utc(2011, 10, 6, 8, 59), - utc(2011, 10, 6, 9, 0), - utc(2011, 10, 6, 9, 1) - ]); - }, - "UTC": { - topic: function(range) { - return range.utc; - }, - "returns minutes": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 23, 59), utc(2011, 0, 1, 0, 2)), [ - utc(2010, 11, 31, 23, 59), - utc(2011, 0, 1, 0, 0), - utc(2011, 0, 1, 0, 1) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 23, 59), utc(2011, 0, 1, 0, 2))[0], utc(2010, 11, 31, 23, 59)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 23, 59), utc(2011, 0, 1, 0, 2))[2], utc(2011, 0, 1, 0, 1)); - }, - "can skip minutes": function(range) { - assert.deepEqual(range(utc(2011, 1, 1, 12, 7), utc(2011, 1, 1, 13, 7), 15), [ - utc(2011, 1, 1, 12, 15), - utc(2011, 1, 1, 12, 30), - utc(2011, 1, 1, 12, 45), - utc(2011, 1, 1, 13, 0) - ]); - }, - "does not observe the start of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 2, 13, 9, 59), utc(2011, 2, 13, 10, 2)), [ - utc(2011, 2, 13, 9, 59), - utc(2011, 2, 13, 10, 0), - utc(2011, 2, 13, 10, 1) - ]); - }, - "does not observe the end of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 10, 6, 8, 59), utc(2011, 10, 6, 9, 2)), [ - utc(2011, 10, 6, 8, 59), - utc(2011, 10, 6, 9, 0), - utc(2011, 10, 6, 9, 1) - ]); - } - } - } -}); - -suite.export(module); diff --git a/test/time/month-test.js b/test/time/month-test.js deleted file mode 100644 index 10f349df70731e..00000000000000 --- a/test/time/month-test.js +++ /dev/null @@ -1,150 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.month"); - -suite.addBatch({ - "month": { - topic: load("time/month").expression("d3.time.month"), - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns months": function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23, 59, 59)), local(2010, 11, 01)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 00)), local(2011, 00, 01)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 01)), local(2011, 00, 01)); - }, - "observes the start of daylight savings time": function(floor) { - assert.deepEqual(floor(local(2011, 02, 13, 01)), local(2011, 02, 01)); - }, - "observes the end of the daylight savings time": function(floor) { - assert.deepEqual(floor(local(2011, 10, 06, 01)), local(2011, 10, 01)); - }, - "correctly handles years in the first century": function(floor) { - assert.deepEqual(floor(local(0011, 10, 06, 07)), local(0011, 10, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns months": function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 31, 23, 59, 59)), local(2011, 00, 01)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 00)), local(2011, 00, 01)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 01)), local(2011, 01, 01)); - }, - "observes the start of daylight savings time": function(ceil) { - assert.deepEqual(ceil(local(2011, 02, 13, 01)), local(2011, 03, 01)); - }, - "observes the end of the daylight savings time": function(ceil) { - assert.deepEqual(ceil(local(2011, 10, 06, 01)), local(2011, 11, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = local(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, local(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), +1), local(2011, 00, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 456), -2), local(2010, 09, 31, 23, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 01), -1), local(2010, 10, 01)); - assert.deepEqual(offset(local(2011, 00, 01), -2), local(2010, 10, 01)); - assert.deepEqual(offset(local(2011, 00, 01), -1), local(2010, 11, 01)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(local(2010, 10, 01), +1), local(2010, 11, 01)); - assert.deepEqual(offset(local(2010, 10, 01), +2), local(2011, 00, 01)); - assert.deepEqual(offset(local(2010, 11, 01), +1), local(2011, 00, 01)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), 0), local(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58, 000), 0), local(2010, 11, 31, 23, 59, 58, 000)); - } - }, - "UTC": { - topic: function(interval) { - return interval.utc; - }, - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns months": function(floor) { - assert.deepEqual(floor(utc(2010, 11, 31, 23, 59, 59)), utc(2010, 11, 01)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 00)), utc(2011, 00, 01)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 01)), utc(2011, 00, 01)); - }, - "does not observe the start of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 02, 13, 01)), utc(2011, 02, 01)); - }, - "does not observe the end of the daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 10, 06, 01)), utc(2011, 10, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns months": function(ceil) { - assert.deepEqual(ceil(utc(2010, 11, 31, 23, 59, 59)), utc(2011, 00, 01)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 00)), utc(2011, 00, 01)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 01)), utc(2011, 01, 01)); - }, - "does not observe the start of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 02, 13, 01)), utc(2011, 03, 01)); - }, - "does not observe the end of the daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 10, 06, 01)), utc(2011, 11, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = utc(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, utc(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), +1), utc(2011, 00, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 456), -2), utc(2010, 09, 31, 23, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 01), -1), utc(2010, 10, 01)); - assert.deepEqual(offset(utc(2011, 00, 01), -2), utc(2010, 10, 01)); - assert.deepEqual(offset(utc(2011, 00, 01), -1), utc(2010, 11, 01)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 10, 01), +1), utc(2010, 11, 01)); - assert.deepEqual(offset(utc(2010, 10, 01), +2), utc(2011, 00, 01)); - assert.deepEqual(offset(utc(2010, 11, 01), +1), utc(2011, 00, 01)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), 0), utc(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58, 000), 0), utc(2010, 11, 31, 23, 59, 58, 000)); - } - } - } - } -}); - -suite.export(module); diff --git a/test/time/months-test.js b/test/time/months-test.js deleted file mode 100644 index 82bca86baf8191..00000000000000 --- a/test/time/months-test.js +++ /dev/null @@ -1,95 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.months"); - -suite.addBatch({ - "months": { - topic: load("time/month").expression("d3.time.months"), - "returns months": function(range) { - assert.deepEqual(range(local(2010, 10, 31), local(2011, 2, 1)), [ - local(2010, 11, 1), - local(2011, 0, 1), - local(2011, 1, 1) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(local(2010, 10, 31), local(2011, 2, 1))[0], local(2010, 11, 1)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(local(2010, 10, 31), local(2011, 2, 1))[2], local(2011, 1, 1)); - }, - "can skip months": function(range) { - assert.deepEqual(range(local(2011, 1, 1), local(2012, 1, 1), 3), [ - local(2011, 3, 1), - local(2011, 6, 1), - local(2011, 9, 1), - local(2012, 0, 1) - ]); - }, - "observes start of daylight savings time": function(range) { - assert.deepEqual(range(local(2011, 0, 1), local(2011, 4, 1)), [ - local(2011, 0, 1), - local(2011, 1, 1), - local(2011, 2, 1), - local(2011, 3, 1) - ]); - }, - "observes end of daylight savings time": function(range) { - assert.deepEqual(range(local(2011, 9, 1), local(2012, 1, 1)), [ - local(2011, 9, 1), - local(2011, 10, 1), - local(2011, 11, 1), - local(2012, 0, 1) - ]); - }, - "UTC": { - topic: function(range) { - return range.utc; - }, - "returns months": function(range) { - assert.deepEqual(range(utc(2010, 10, 31), utc(2011, 2, 1)), [ - utc(2010, 11, 1), - utc(2011, 0, 1), - utc(2011, 1, 1) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(utc(2010, 10, 31), utc(2011, 2, 1))[0], utc(2010, 11, 1)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(utc(2010, 10, 31), utc(2011, 2, 1))[2], utc(2011, 1, 1)); - }, - "can skip months": function(range) { - assert.deepEqual(range(utc(2011, 1, 1), utc(2012, 1, 1), 3), [ - utc(2011, 3, 1), - utc(2011, 6, 1), - utc(2011, 9, 1), - utc(2012, 0, 1) - ]); - }, - "does not observe the start of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 0, 1), utc(2011, 4, 1)), [ - utc(2011, 0, 1), - utc(2011, 1, 1), - utc(2011, 2, 1), - utc(2011, 3, 1) - ]); - }, - "does not observe the end of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 9, 1), utc(2012, 1, 1)), [ - utc(2011, 9, 1), - utc(2011, 10, 1), - utc(2011, 11, 1), - utc(2012, 0, 1) - ]); - } - } - } -}); - -suite.export(module); diff --git a/test/time/scale-test.js b/test/time/scale-test.js deleted file mode 100644 index a213a934489c7b..00000000000000 --- a/test/time/scale-test.js +++ /dev/null @@ -1,679 +0,0 @@ -var vows = require("vows"), - _ = require("../../"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.scale"); - -suite.addBatch({ - "scale": { - topic: load("time/scale").expression("d3.time.scale").document(), - - "nice": { - "rounds using the specified time interval": function(scale) { - var x = scale().domain([local(2009, 0, 1, 0, 12), local(2009, 0, 1, 23, 48)]); - assert.deepEqual(x.nice(_.time.day).domain(), [local(2009, 0, 1), local(2009, 0, 2)]); - assert.deepEqual(x.nice(_.time.week).domain(), [local(2008, 11, 28), local(2009, 0, 4)]); - assert.deepEqual(x.nice(_.time.month).domain(), [local(2008, 11, 1), local(2009, 1, 1)]); - assert.deepEqual(x.nice(_.time.year).domain(), [local(2008, 0, 1), local(2010, 0, 1)]); - }, - "rounds using the specified time interval and skip": function(scale) { - var x = scale().domain([local(2009, 0, 1, 0, 12), local(2009, 0, 1, 23, 48)]); - assert.deepEqual(x.nice(_.time.day, 3).domain(), [local(2009, 0, 1), local(2009, 0, 4)]); - assert.deepEqual(x.nice(_.time.week, 2).domain(), [local(2008, 11, 21), local(2009, 0, 4)]); - assert.deepEqual(x.nice(_.time.month, 3).domain(), [local(2008, 9, 1), local(2009, 3, 1)]); - assert.deepEqual(x.nice(_.time.year, 10).domain(), [local(2000, 0, 1), local(2010, 0, 1)]); - }, - "rounds using the specified count": function(scale) { - var x = scale().domain([local(2009, 0, 1, 0, 17), local(2009, 0, 1, 23, 42)]); - assert.deepEqual(x.nice(100).domain(), [local(2009, 0, 1, 0, 15), local(2009, 0, 1, 23, 45)]); - assert.deepEqual(x.nice(10).domain(), [local(2009, 0, 1), local(2009, 0, 2)]); - }, - "rounds with a default count of ten if no arguments": function(scale) { - var x = scale().domain([local(2009, 0, 1, 0, 17), local(2009, 0, 1, 23, 42)]); - assert.deepEqual(x.nice().domain(), [local(2009, 0, 1), local(2009, 0, 2)]); - }, - "works on degenerate domains": function(scale) { - var x = scale().domain([local(2009, 0, 1, 0, 12), local(2009, 0, 1, 0, 12)]); - assert.deepEqual(x.nice(_.time.day).domain(), [local(2009, 0, 1), local(2009, 0, 2)]); - }, - "nicing a polylinear domain only affects the extent": function(linear) { - var x = linear().domain([local(2009, 0, 1, 0, 12), local(2009, 0, 1, 23, 48), local(2009, 0, 2, 23, 48)]).nice(_.time.day); - assert.deepEqual(x.domain(), [local(2009, 0, 1), local(2009, 0, 1, 23, 48), local(2009, 0, 3)]); - } - }, - - "copy": { - "changes to the domain are isolated": function(scale) { - var x = scale().domain([local(2009, 0, 1), local(2010, 0, 1)]), y = x.copy(); - x.domain([local(2010, 0, 1), local(2011, 0, 1)]); - assert.deepEqual(y.domain(), [local(2009, 0, 1), local(2010, 0, 1)]); - assert.equal(x(local(2010, 0, 1)), 0); - assert.equal(y(local(2010, 0, 1)), 1); - y.domain([local(2011, 0, 1), local(2012, 0, 1)]); - assert.equal(x(local(2011, 0, 1)), 1); - assert.equal(y(local(2011, 0, 1)), 0); - assert.deepEqual(x.domain(), [local(2010, 0, 1), local(2011, 0, 1)]); - assert.deepEqual(y.domain(), [local(2011, 0, 1), local(2012, 0, 1)]); - }, - "changes to the range are isolated": function(scale) { - var x = scale().domain([local(2009, 0, 1), local(2010, 0, 1)]), y = x.copy(); - x.range([1, 2]); - assert.deepEqual(x.invert(1), local(2009, 0, 1)); - assert.deepEqual(y.invert(1), local(2010, 0, 1)); - assert.deepEqual(y.range(), [0, 1]); - y.range([2, 3]); - assert.deepEqual(x.invert(2), local(2010, 0, 1)); - assert.deepEqual(y.invert(2), local(2009, 0, 1)); - assert.deepEqual(x.range(), [1, 2]); - assert.deepEqual(y.range(), [2, 3]); - }, - "changes to the interpolator are isolated": function(scale) { - var x = scale().domain([local(2009, 0, 1), local(2010, 0, 1)]).range(["red", "blue"]), - i = x.interpolate(), - y = x.copy(); - x.interpolate(_.interpolateHsl); - assert.equal(x(local(2009, 6, 1)), "#ff00fd"); - assert.equal(y(local(2009, 6, 1)), "#81007e"); - assert.equal(y.interpolate(), i); - }, - "changes to clamping are isolated": function(scale) { - var x = scale().domain([local(2009, 0, 1), local(2010, 0, 1)]).clamp(true), y = x.copy(); - x.clamp(false); - assert.equal(x(local(2011, 0, 1)), 2); - assert.equal(y(local(2011, 0, 1)), 1); - assert.isTrue(y.clamp()); - y.clamp(false); - assert.equal(x(local(2011, 0, 1)), 2); - assert.equal(y(local(2011, 0, 1)), 2); - assert.isFalse(x.clamp()); - } - }, - - "ticks": { - "observes explicit tick interval": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 1, 0), local(2011, 0, 1, 12, 4, 4)]); - assert.deepEqual(x.ticks(_.time.minute), [ - local(2011, 0, 1, 12, 1), - local(2011, 0, 1, 12, 2), - local(2011, 0, 1, 12, 3), - local(2011, 0, 1, 12, 4) - ]); - }, - "observes explicit tick interval and step": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 0, 0), local(2011, 0, 1, 12, 33, 4)]); - assert.deepEqual(x.ticks(_.time.minute, 10), [ - local(2011, 0, 1, 12, 0), - local(2011, 0, 1, 12, 10), - local(2011, 0, 1, 12, 20), - local(2011, 0, 1, 12, 30) - ]); - }, - "(deprecated) observes explicit tick range": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 1, 0), local(2011, 0, 1, 12, 4, 4)]); - assert.deepEqual(x.ticks(_.time.minutes), [ - local(2011, 0, 1, 12, 1), - local(2011, 0, 1, 12, 2), - local(2011, 0, 1, 12, 3), - local(2011, 0, 1, 12, 4) - ]); - }, - "(deprecated) observes explicit tick range and step": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 0, 0), local(2011, 0, 1, 12, 33, 4)]); - assert.deepEqual(x.ticks(_.time.minutes, 10), [ - local(2011, 0, 1, 12, 0), - local(2011, 0, 1, 12, 10), - local(2011, 0, 1, 12, 20), - local(2011, 0, 1, 12, 30) - ]); - }, - "generates sub-second ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 0, 0), local(2011, 0, 1, 12, 0, 1)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 0, 0, 0), - local(2011, 0, 1, 12, 0, 0, 200), - local(2011, 0, 1, 12, 0, 0, 400), - local(2011, 0, 1, 12, 0, 0, 600), - local(2011, 0, 1, 12, 0, 0, 800), - local(2011, 0, 1, 12, 0, 1, 0) - ]); - }, - "generates 1-second ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 0, 0), local(2011, 0, 1, 12, 0, 4)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 0, 0), - local(2011, 0, 1, 12, 0, 1), - local(2011, 0, 1, 12, 0, 2), - local(2011, 0, 1, 12, 0, 3), - local(2011, 0, 1, 12, 0, 4) - ]); - }, - "generates 5-second ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 0, 0), local(2011, 0, 1, 12, 0, 20)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 0, 0), - local(2011, 0, 1, 12, 0, 5), - local(2011, 0, 1, 12, 0, 10), - local(2011, 0, 1, 12, 0, 15), - local(2011, 0, 1, 12, 0, 20) - ]); - }, - "generates 15-second ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 0, 0), local(2011, 0, 1, 12, 0, 50)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 0, 0), - local(2011, 0, 1, 12, 0, 15), - local(2011, 0, 1, 12, 0, 30), - local(2011, 0, 1, 12, 0, 45) - ]); - }, - "generates 30-second ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 0, 0), local(2011, 0, 1, 12, 1, 50)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 0, 0), - local(2011, 0, 1, 12, 0, 30), - local(2011, 0, 1, 12, 1, 0), - local(2011, 0, 1, 12, 1, 30) - ]); - }, - "generates 1-minute ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 0, 27), local(2011, 0, 1, 12, 4, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 1), - local(2011, 0, 1, 12, 2), - local(2011, 0, 1, 12, 3), - local(2011, 0, 1, 12, 4) - ]); - }, - "generates 5-minute ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 3, 27), local(2011, 0, 1, 12, 21, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 5), - local(2011, 0, 1, 12, 10), - local(2011, 0, 1, 12, 15), - local(2011, 0, 1, 12, 20) - ]); - }, - "generates 15-minute ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 8, 27), local(2011, 0, 1, 13, 4, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 15), - local(2011, 0, 1, 12, 30), - local(2011, 0, 1, 12, 45), - local(2011, 0, 1, 13, 0) - ]); - }, - "generates 30-minute ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 28, 27), local(2011, 0, 1, 14, 4, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 12, 30), - local(2011, 0, 1, 13, 0), - local(2011, 0, 1, 13, 30), - local(2011, 0, 1, 14, 0) - ]); - }, - "generates 1-hour ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 12, 28, 27), local(2011, 0, 1, 16, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 13, 0), - local(2011, 0, 1, 14, 0), - local(2011, 0, 1, 15, 0), - local(2011, 0, 1, 16, 0) - ]); - }, - "generates 3-hour ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 14, 28, 27), local(2011, 0, 2, 1, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 15, 0), - local(2011, 0, 1, 18, 0), - local(2011, 0, 1, 21, 0), - local(2011, 0, 2, 0, 0) - ]); - }, - "generates 6-hour ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 16, 28, 27), local(2011, 0, 2, 14, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 18, 0), - local(2011, 0, 2, 0, 0), - local(2011, 0, 2, 6, 0), - local(2011, 0, 2, 12, 0) - ]); - }, - "generates 12-hour ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 16, 28, 27), local(2011, 0, 3, 21, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 2, 0, 0), - local(2011, 0, 2, 12, 0), - local(2011, 0, 3, 0, 0), - local(2011, 0, 3, 12, 0) - ]); - }, - "generates 1-day ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 16, 28, 27), local(2011, 0, 5, 21, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 2, 0, 0), - local(2011, 0, 3, 0, 0), - local(2011, 0, 4, 0, 0), - local(2011, 0, 5, 0, 0) - ]); - }, - "generates 2-day ticks": function(scale) { - var x = scale().domain([local(2011, 0, 2, 16, 28, 27), local(2011, 0, 9, 21, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 3, 0, 0), - local(2011, 0, 5, 0, 0), - local(2011, 0, 7, 0, 0), - local(2011, 0, 9, 0, 0) - ]); - }, - "generates 1-week ticks": function(scale) { - var x = scale().domain([local(2011, 0, 1, 16, 28, 27), local(2011, 0, 23, 21, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 2, 0, 0), - local(2011, 0, 9, 0, 0), - local(2011, 0, 16, 0, 0), - local(2011, 0, 23, 0, 0) - ]); - }, - "generates 1-month ticks": function(scale) { - var x = scale().domain([local(2011, 0, 18), local(2011, 4, 2)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 1, 1, 0, 0), - local(2011, 2, 1, 0, 0), - local(2011, 3, 1, 0, 0), - local(2011, 4, 1, 0, 0) - ]); - }, - "generates 3-month ticks": function(scale) { - var x = scale().domain([local(2010, 11, 18), local(2011, 10, 2)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 0, 0), - local(2011, 3, 1, 0, 0), - local(2011, 6, 1, 0, 0), - local(2011, 9, 1, 0, 0) - ]); - }, - "generates 1-year ticks": function(scale) { - var x = scale().domain([local(2010, 11, 18), local(2014, 2, 2)]); - assert.deepEqual(x.ticks(4), [ - local(2011, 0, 1, 0, 0), - local(2012, 0, 1, 0, 0), - local(2013, 0, 1, 0, 0), - local(2014, 0, 1, 0, 0) - ]); - }, - "generates multi-year ticks": function(scale) { - var x = scale().domain([local(0, 11, 18), local(2014, 2, 2)]); - assert.deepEqual(x.ticks(6), [ - local( 500, 0, 1, 0, 0), - local(1000, 0, 1, 0, 0), - local(1500, 0, 1, 0, 0), - local(2000, 0, 1, 0, 0) - ]); - }, - "returns one tick for degenerate empty domain": function(scale) { - var x = scale().domain([local(2014, 2, 2), local(2014, 2, 2)]); - assert.deepEqual(x.ticks(6), [local(2014, 2, 2)]); - } - }, - - "tickFormat": { - topic: function(scale) { - return scale().tickFormat(); - }, - "formats year on New Year's": function(format) { - assert.equal(format(local(2011, 0, 1)), "2011"); - assert.equal(format(local(2012, 0, 1)), "2012"); - assert.equal(format(local(2013, 0, 1)), "2013"); - }, - "formats month on the 1st of each month": function(format) { - assert.equal(format(local(2011, 1, 1)), "February"); - assert.equal(format(local(2011, 2, 1)), "March"); - assert.equal(format(local(2011, 3, 1)), "April"); - }, - "formats week on Sunday midnight": function(format) { - assert.equal(format(local(2011, 1, 6)), "Feb 06"); - assert.equal(format(local(2011, 1, 13)), "Feb 13"); - assert.equal(format(local(2011, 1, 20)), "Feb 20"); - }, - "formats date on midnight": function(format) { - assert.equal(format(local(2011, 1, 2)), "Wed 02"); - assert.equal(format(local(2011, 1, 3)), "Thu 03"); - assert.equal(format(local(2011, 1, 4)), "Fri 04"); - }, - "formats hour on minute zero": function(format) { - assert.equal(format(local(2011, 1, 2, 11)), "11 AM"); - assert.equal(format(local(2011, 1, 2, 12)), "12 PM"); - assert.equal(format(local(2011, 1, 2, 13)), "01 PM"); - }, - "formats minute on second zero": function(format) { - assert.equal(format(local(2011, 1, 2, 11, 59)), "11:59"); - assert.equal(format(local(2011, 1, 2, 12, 1)), "12:01"); - assert.equal(format(local(2011, 1, 2, 12, 2)), "12:02"); - }, - "otherwise, formats second": function(format) { - assert.equal(format(local(2011, 1, 2, 12, 1, 9)), ":09"); - assert.equal(format(local(2011, 1, 2, 12, 1, 10)), ":10"); - assert.equal(format(local(2011, 1, 2, 12, 1, 11)), ":11"); - } - } - } -}); - -suite.addBatch({ - "scale.utc": { - topic: load("time/scale-utc").expression("d3.time.scale.utc").document(), - - "nice": { - "rounds using the specified time interval": function(scale) { - var x = scale().domain([utc(2009, 0, 1, 0, 12), utc(2009, 0, 1, 23, 48)]); - assert.deepEqual(x.nice(_.time.day.utc).domain(), [utc(2009, 0, 1), utc(2009, 0, 2)]); - assert.deepEqual(x.nice(_.time.week.utc).domain(), [utc(2008, 11, 28), utc(2009, 0, 4)]); - assert.deepEqual(x.nice(_.time.month.utc).domain(), [utc(2008, 11, 1), utc(2009, 1, 1)]); - assert.deepEqual(x.nice(_.time.year.utc).domain(), [utc(2008, 0, 1), utc(2010, 0, 1)]); - }, - "rounds using the specified time interval and skip": function(scale) { - var x = scale().domain([utc(2009, 0, 1, 0, 12), utc(2009, 0, 1, 23, 48)]); - assert.deepEqual(x.nice(_.time.day.utc, 3).domain(), [utc(2009, 0, 1), utc(2009, 0, 4)]); - assert.deepEqual(x.nice(_.time.week.utc, 2).domain(), [utc(2008, 11, 21), utc(2009, 0, 4)]); - assert.deepEqual(x.nice(_.time.month.utc, 3).domain(), [utc(2008, 9, 1), utc(2009, 3, 1)]); - assert.deepEqual(x.nice(_.time.year.utc, 10).domain(), [utc(2000, 0, 1), utc(2010, 0, 1)]); - }, - "rounds using the specified count": function(scale) { - var x = scale().domain([utc(2009, 0, 1, 0, 17), utc(2009, 0, 1, 23, 42)]); - assert.deepEqual(x.nice(100).domain(), [utc(2009, 0, 1, 0, 15), utc(2009, 0, 1, 23, 45)]); - assert.deepEqual(x.nice(10).domain(), [utc(2009, 0, 1), utc(2009, 0, 2)]); - }, - "rounds with a default count of ten if no arguments": function(scale) { - var x = scale().domain([utc(2009, 0, 1, 0, 17), utc(2009, 0, 1, 23, 42)]); - assert.deepEqual(x.nice().domain(), [utc(2009, 0, 1), utc(2009, 0, 2)]); - }, - "works on degenerate domains": function(scale) { - var x = scale().domain([utc(2009, 0, 1, 0, 12), utc(2009, 0, 1, 0, 12)]); - assert.deepEqual(x.nice(_.time.day.utc).domain(), [utc(2009, 0, 1), utc(2009, 0, 2)]); - }, - "nicing a polylinear domain only affects the extent": function(linear) { - var x = linear().domain([utc(2009, 0, 1, 0, 12), utc(2009, 0, 1, 23, 48), utc(2009, 0, 2, 23, 48)]).nice(_.time.day.utc); - assert.deepEqual(x.domain(), [utc(2009, 0, 1), utc(2009, 0, 1, 23, 48), utc(2009, 0, 3)]); - } - }, - - "ticks": { - "observes explicit tick interval": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 1, 0), utc(2011, 0, 1, 12, 4, 4)]); - assert.deepEqual(x.ticks(_.time.minute.utc), [ - utc(2011, 0, 1, 12, 1), - utc(2011, 0, 1, 12, 2), - utc(2011, 0, 1, 12, 3), - utc(2011, 0, 1, 12, 4) - ]); - }, - "observes explicit tick interval and step": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 0, 0), utc(2011, 0, 1, 12, 33, 4)]); - assert.deepEqual(x.ticks(_.time.minute.utc, 10), [ - utc(2011, 0, 1, 12, 0), - utc(2011, 0, 1, 12, 10), - utc(2011, 0, 1, 12, 20), - utc(2011, 0, 1, 12, 30) - ]); - }, - "(deprecated) observes explicit tick range": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 1, 0), utc(2011, 0, 1, 12, 4, 4)]); - assert.deepEqual(x.ticks(_.time.minutes.utc), [ - utc(2011, 0, 1, 12, 1), - utc(2011, 0, 1, 12, 2), - utc(2011, 0, 1, 12, 3), - utc(2011, 0, 1, 12, 4) - ]); - }, - "(deprecated) observes explicit tick range and step": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 0, 0), utc(2011, 0, 1, 12, 33, 4)]); - assert.deepEqual(x.ticks(_.time.minutes.utc, 10), [ - utc(2011, 0, 1, 12, 0), - utc(2011, 0, 1, 12, 10), - utc(2011, 0, 1, 12, 20), - utc(2011, 0, 1, 12, 30) - ]); - }, - "generates sub-second ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 0, 0), utc(2011, 0, 1, 12, 0, 1)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 0, 0, 0), - utc(2011, 0, 1, 12, 0, 0, 200), - utc(2011, 0, 1, 12, 0, 0, 400), - utc(2011, 0, 1, 12, 0, 0, 600), - utc(2011, 0, 1, 12, 0, 0, 800), - utc(2011, 0, 1, 12, 0, 1, 0) - ]); - }, - "generates 1-second ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 0, 0), utc(2011, 0, 1, 12, 0, 4)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 0, 0), - utc(2011, 0, 1, 12, 0, 1), - utc(2011, 0, 1, 12, 0, 2), - utc(2011, 0, 1, 12, 0, 3), - utc(2011, 0, 1, 12, 0, 4) - ]); - }, - "generates 5-second ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 0, 0), utc(2011, 0, 1, 12, 0, 20)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 0, 0), - utc(2011, 0, 1, 12, 0, 5), - utc(2011, 0, 1, 12, 0, 10), - utc(2011, 0, 1, 12, 0, 15), - utc(2011, 0, 1, 12, 0, 20) - ]); - }, - "generates 15-second ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 0, 0), utc(2011, 0, 1, 12, 0, 50)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 0, 0), - utc(2011, 0, 1, 12, 0, 15), - utc(2011, 0, 1, 12, 0, 30), - utc(2011, 0, 1, 12, 0, 45) - ]); - }, - "generates 30-second ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 0, 0), utc(2011, 0, 1, 12, 1, 50)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 0, 0), - utc(2011, 0, 1, 12, 0, 30), - utc(2011, 0, 1, 12, 1, 0), - utc(2011, 0, 1, 12, 1, 30) - ]); - }, - "generates 1-minute ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 0, 27), utc(2011, 0, 1, 12, 4, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 1), - utc(2011, 0, 1, 12, 2), - utc(2011, 0, 1, 12, 3), - utc(2011, 0, 1, 12, 4) - ]); - }, - "generates 5-minute ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 3, 27), utc(2011, 0, 1, 12, 21, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 5), - utc(2011, 0, 1, 12, 10), - utc(2011, 0, 1, 12, 15), - utc(2011, 0, 1, 12, 20) - ]); - }, - "generates 15-minute ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 8, 27), utc(2011, 0, 1, 13, 4, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 15), - utc(2011, 0, 1, 12, 30), - utc(2011, 0, 1, 12, 45), - utc(2011, 0, 1, 13, 0) - ]); - }, - "generates 30-minute ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 28, 27), utc(2011, 0, 1, 14, 4, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 12, 30), - utc(2011, 0, 1, 13, 0), - utc(2011, 0, 1, 13, 30), - utc(2011, 0, 1, 14, 0) - ]); - }, - "generates 1-hour ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 12, 28, 27), utc(2011, 0, 1, 16, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 13, 0), - utc(2011, 0, 1, 14, 0), - utc(2011, 0, 1, 15, 0), - utc(2011, 0, 1, 16, 0) - ]); - }, - "generates 3-hour ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 14, 28, 27), utc(2011, 0, 2, 1, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 15, 0), - utc(2011, 0, 1, 18, 0), - utc(2011, 0, 1, 21, 0), - utc(2011, 0, 2, 0, 0) - ]); - }, - "generates 6-hour ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 16, 28, 27), utc(2011, 0, 2, 14, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 18, 0), - utc(2011, 0, 2, 0, 0), - utc(2011, 0, 2, 6, 0), - utc(2011, 0, 2, 12, 0) - ]); - }, - "generates 12-hour ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 16, 28, 27), utc(2011, 0, 3, 21, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 2, 0, 0), - utc(2011, 0, 2, 12, 0), - utc(2011, 0, 3, 0, 0), - utc(2011, 0, 3, 12, 0) - ]); - }, - "generates 1-day ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 16, 28, 27), utc(2011, 0, 5, 21, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 2, 0, 0), - utc(2011, 0, 3, 0, 0), - utc(2011, 0, 4, 0, 0), - utc(2011, 0, 5, 0, 0) - ]); - }, - "generates 2-day ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 2, 16, 28, 27), utc(2011, 0, 9, 21, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 3, 0, 0), - utc(2011, 0, 5, 0, 0), - utc(2011, 0, 7, 0, 0), - utc(2011, 0, 9, 0, 0) - ]); - }, - "generates 1-week ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 1, 16, 28, 27), utc(2011, 0, 23, 21, 34, 12)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 2, 0, 0), - utc(2011, 0, 9, 0, 0), - utc(2011, 0, 16, 0, 0), - utc(2011, 0, 23, 0, 0) - ]); - }, - "generates 1-month ticks": function(scale) { - var x = scale().domain([utc(2011, 0, 18), utc(2011, 4, 2)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 1, 1, 0, 0), - utc(2011, 2, 1, 0, 0), - utc(2011, 3, 1, 0, 0), - utc(2011, 4, 1, 0, 0) - ]); - }, - "generates 3-month ticks": function(scale) { - var x = scale().domain([utc(2010, 11, 18), utc(2011, 10, 2)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 0, 0), - utc(2011, 3, 1, 0, 0), - utc(2011, 6, 1, 0, 0), - utc(2011, 9, 1, 0, 0) - ]); - }, - "generates 1-year ticks": function(scale) { - var x = scale().domain([utc(2010, 11, 18), utc(2014, 2, 2)]); - assert.deepEqual(x.ticks(4), [ - utc(2011, 0, 1, 0, 0), - utc(2012, 0, 1, 0, 0), - utc(2013, 0, 1, 0, 0), - utc(2014, 0, 1, 0, 0) - ]); - }, - "generates multi-year ticks": function(scale) { - var x = scale().domain([utc(0, 11, 18), utc(2014, 2, 2)]); - assert.deepEqual(x.ticks(6), [ - utc( 500, 0, 1, 0, 0), - utc(1000, 0, 1, 0, 0), - utc(1500, 0, 1, 0, 0), - utc(2000, 0, 1, 0, 0) - ]); - }, - "returns one tick for degenerate empty domain": function(scale) { - var x = scale().domain([utc(2014, 2, 2), utc(2014, 2, 2)]); - assert.deepEqual(x.ticks(6), [utc(2014, 2, 2)]); - } - }, - - "tickFormat": { - topic: function(scale) { - return scale().tickFormat(); - }, - "formats year on New Year's": function(format) { - assert.equal(format(utc(2011, 0, 1)), "2011"); - assert.equal(format(utc(2012, 0, 1)), "2012"); - assert.equal(format(utc(2013, 0, 1)), "2013"); - }, - "formats month on the 1st of each month": function(format) { - assert.equal(format(utc(2011, 1, 1)), "February"); - assert.equal(format(utc(2011, 2, 1)), "March"); - assert.equal(format(utc(2011, 3, 1)), "April"); - }, - "formats week on Sunday midnight": function(format) { - assert.equal(format(utc(2011, 1, 6)), "Feb 06"); - assert.equal(format(utc(2011, 1, 13)), "Feb 13"); - assert.equal(format(utc(2011, 1, 20)), "Feb 20"); - }, - "formats date on midnight": function(format) { - assert.equal(format(utc(2011, 1, 2)), "Wed 02"); - assert.equal(format(utc(2011, 1, 3)), "Thu 03"); - assert.equal(format(utc(2011, 1, 4)), "Fri 04"); - }, - "formats hour on minute zero": function(format) { - assert.equal(format(utc(2011, 1, 2, 11)), "11 AM"); - assert.equal(format(utc(2011, 1, 2, 12)), "12 PM"); - assert.equal(format(utc(2011, 1, 2, 13)), "01 PM"); - }, - "formats minute on second zero": function(format) { - assert.equal(format(utc(2011, 1, 2, 11, 59)), "11:59"); - assert.equal(format(utc(2011, 1, 2, 12, 1)), "12:01"); - assert.equal(format(utc(2011, 1, 2, 12, 2)), "12:02"); - }, - "formats second on millisecond zero": function(format) { - assert.equal(format(utc(2011, 1, 2, 12, 1, 9)), ":09"); - assert.equal(format(utc(2011, 1, 2, 12, 1, 10)), ":10"); - assert.equal(format(utc(2011, 1, 2, 12, 1, 11)), ":11"); - }, - "otherwise, formats milliseconds": function(format) { - assert.equal(format(utc(2011, 1, 2, 12, 1, 0, 9)), ".009"); - assert.equal(format(utc(2011, 1, 2, 12, 1, 0, 10)), ".010"); - assert.equal(format(utc(2011, 1, 2, 12, 1, 0, 11)), ".011"); - } - } - } -}); - -suite.export(module); diff --git a/test/time/second-test.js b/test/time/second-test.js deleted file mode 100644 index e740d3a29eaf67..00000000000000 --- a/test/time/second-test.js +++ /dev/null @@ -1,143 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.second"); - -suite.addBatch({ - "second": { - topic: load("time/second").expression("d3.time.second"), - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns seconds": function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23, 59, 59, 999)), local(2010, 11, 31, 23, 59, 59)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 00, 000)), local(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 00, 001)), local(2011, 00, 01, 00, 00, 00)); - } - }, - "round": { - topic: function(interval) { - return interval.round; - }, - "returns seconds": function(round) { - assert.deepEqual(round(local(2010, 11, 31, 23, 59, 59, 999)), local(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(round(local(2011, 00, 01, 00, 00, 00, 499)), local(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(round(local(2011, 00, 01, 00, 00, 00, 500)), local(2011, 00, 01, 00, 00, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns seconds": function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 31, 23, 59, 59, 999)), local(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 00, 000)), local(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 00, 001)), local(2011, 00, 01, 00, 00, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = local(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, local(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), +1), local(2011, 00, 01, 00, 00, 00, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 456), -2), local(2010, 11, 31, 23, 59, 57, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59), -1), local(2010, 11, 31, 23, 59, 58)); - assert.deepEqual(offset(local(2011, 00, 01, 00, 00, 00), -2), local(2010, 11, 31, 23, 59, 58)); - assert.deepEqual(offset(local(2011, 00, 01, 00, 00, 00), -1), local(2010, 11, 31, 23, 59, 59)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58), +1), local(2010, 11, 31, 23, 59, 59)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58), +2), local(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59), +1), local(2011, 00, 01, 00, 00, 00)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), 0), local(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58, 000), 0), local(2010, 11, 31, 23, 59, 58, 000)); - } - }, - "UTC": { - topic: function(interval) { - return interval.utc; - }, - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns seconds": function(floor) { - assert.deepEqual(floor(utc(2010, 11, 31, 23, 59, 59, 999)), utc(2010, 11, 31, 23, 59, 59)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 00, 000)), utc(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 00, 001)), utc(2011, 00, 01, 00, 00, 00)); - } - }, - "round": { - topic: function(interval) { - return interval.round; - }, - "returns seconds": function(round) { - assert.deepEqual(round(utc(2010, 11, 31, 23, 59, 59, 999)), utc(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(round(utc(2011, 00, 01, 00, 00, 00, 499)), utc(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(round(utc(2011, 00, 01, 00, 00, 00, 500)), utc(2011, 00, 01, 00, 00, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns seconds": function(ceil) { - assert.deepEqual(ceil(utc(2010, 11, 31, 23, 59, 59, 999)), utc(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 00, 000)), utc(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 00, 001)), utc(2011, 00, 01, 00, 00, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = utc(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, utc(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), +1), utc(2011, 00, 01, 00, 00, 00, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 456), -2), utc(2010, 11, 31, 23, 59, 57, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59), -1), utc(2010, 11, 31, 23, 59, 58)); - assert.deepEqual(offset(utc(2011, 00, 01, 00, 00, 00), -2), utc(2010, 11, 31, 23, 59, 58)); - assert.deepEqual(offset(utc(2011, 00, 01, 00, 00, 00), -1), utc(2010, 11, 31, 23, 59, 59)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58), +1), utc(2010, 11, 31, 23, 59, 59)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58), +2), utc(2011, 00, 01, 00, 00, 00)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59), +1), utc(2011, 00, 01, 00, 00, 00)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), 0), utc(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58, 000), 0), utc(2010, 11, 31, 23, 59, 58, 000)); - } - } - } - } -}); - -suite.export(module); diff --git a/test/time/seconds-test.js b/test/time/seconds-test.js deleted file mode 100644 index e8c6ab44867de7..00000000000000 --- a/test/time/seconds-test.js +++ /dev/null @@ -1,91 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.seconds"); - -suite.addBatch({ - "seconds": { - topic: load("time/second").expression("d3.time.seconds"), - "returns seconds": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 23, 59, 59), local(2011, 0, 1, 0, 0, 2)), [ - local(2010, 11, 31, 23, 59, 59), - local(2011, 0, 1, 0, 0, 0), - local(2011, 0, 1, 0, 0, 1) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 23, 59, 59), local(2011, 0, 1, 0, 0, 2))[0], local(2010, 11, 31, 23, 59, 59)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(local(2010, 11, 31, 23, 59, 59), local(2011, 0, 1, 0, 0, 2))[2], local(2011, 0, 1, 0, 0, 1)); - }, - "can skip seconds": function(range) { - assert.deepEqual(range(local(2011, 1, 1, 12, 0, 7), local(2011, 1, 1, 12, 1, 7), 15), [ - local(2011, 1, 1, 12, 0, 15), - local(2011, 1, 1, 12, 0, 30), - local(2011, 1, 1, 12, 0, 45), - local(2011, 1, 1, 12, 1, 0) - ]); - }, - "observes start of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 2, 13, 9, 59, 59), utc(2011, 2, 13, 10, 0, 2)), [ - utc(2011, 2, 13, 9, 59, 59), - utc(2011, 2, 13, 10, 0, 0), - utc(2011, 2, 13, 10, 0, 1) - ]); - }, - "observes end of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 10, 6, 8, 59, 59), utc(2011, 10, 6, 9, 0, 2)), [ - utc(2011, 10, 6, 8, 59, 59), - utc(2011, 10, 6, 9, 0, 0), - utc(2011, 10, 6, 9, 0, 1) - ]); - }, - "UTC": { - topic: function(range) { - return range.utc; - }, - "returns seconds": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 23, 59, 59), utc(2011, 0, 1, 0, 0, 2)), [ - utc(2010, 11, 31, 23, 59, 59), - utc(2011, 0, 1, 0, 0, 0), - utc(2011, 0, 1, 0, 0, 1) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 23, 59, 59), utc(2011, 0, 1, 0, 0, 2))[0], utc(2010, 11, 31, 23, 59, 59)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 31, 23, 59, 59), utc(2011, 0, 1, 0, 0, 2))[2], utc(2011, 0, 1, 0, 0, 1)); - }, - "can skip seconds": function(range) { - assert.deepEqual(range(utc(2011, 1, 1, 12, 0, 7), utc(2011, 1, 1, 12, 1, 7), 15), [ - utc(2011, 1, 1, 12, 0, 15), - utc(2011, 1, 1, 12, 0, 30), - utc(2011, 1, 1, 12, 0, 45), - utc(2011, 1, 1, 12, 1, 0) - ]); - }, - "does not observe the start of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 2, 13, 9, 59, 59), utc(2011, 2, 13, 10, 0, 2)), [ - utc(2011, 2, 13, 9, 59, 59), - utc(2011, 2, 13, 10, 0, 0), - utc(2011, 2, 13, 10, 0, 1) - ]); - }, - "does not observe the end of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 10, 6, 8, 59, 59), utc(2011, 10, 6, 9, 0, 2)), [ - utc(2011, 10, 6, 8, 59, 59), - utc(2011, 10, 6, 9, 0, 0), - utc(2011, 10, 6, 9, 0, 1) - ]); - } - } - } -}); - -suite.export(module); diff --git a/test/time/time.js b/test/time/time.js deleted file mode 100644 index df18dd55ec01b2..00000000000000 --- a/test/time/time.js +++ /dev/null @@ -1,30 +0,0 @@ -var offset = 0; - -exports.local = function(year, month, day, hours, minutes, seconds, milliseconds) { - var date = new Date(); - date.setFullYear(year, month, day); - date.setHours(hours || 0, offset + (minutes || 0), seconds || 0, milliseconds || 0); - return date; -}; - -exports.utc = function(year, month, day, hours, minutes, seconds, milliseconds) { - var date = new Date(); - date.setUTCFullYear(year, month, day); - date.setUTCHours(hours || 0, minutes || 0, seconds || 0, milliseconds || 0); - return date; -}; - -exports.zone = function(tzOffset, scope) { - return function() { - var o = Date.prototype.getTimezoneOffset; - try { - // Note: assumes the dates are not in DST. - offset = -tzOffset - new Date(0).getTimezoneOffset(); - Date.prototype.getTimezoneOffset = function() { return offset; }; - scope.apply(this, arguments); - } finally { - offset = 0; - Date.prototype.getTimezoneOffset = o; - } - }; -}; diff --git a/test/time/week-test.js b/test/time/week-test.js deleted file mode 100644 index f0db1f7f18d50c..00000000000000 --- a/test/time/week-test.js +++ /dev/null @@ -1,162 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.week"); - -suite.addBatch({ - "week": { - topic: load("time/week").expression("d3.time.week"), - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns sundays": function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23, 59, 59)), local(2010, 11, 26)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 00)), local(2010, 11, 26)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 01)), local(2010, 11, 26)); - assert.deepEqual(floor(local(2011, 00, 01, 23, 59, 59)), local(2010, 11, 26)); - assert.deepEqual(floor(local(2011, 00, 02, 00, 00, 00)), local(2011, 00, 02)); - assert.deepEqual(floor(local(2011, 00, 02, 00, 00, 01)), local(2011, 00, 02)); - }, - "observes the start of daylight savings time": function(floor) { - assert.deepEqual(floor(local(2011, 02, 13, 01)), local(2011, 02, 13)); - }, - "observes the end of the daylight savings time": function(floor) { - assert.deepEqual(floor(local(2011, 10, 06, 01)), local(2011, 10, 06)); - }, - "correctly handles years in the first century": function(floor) { - assert.deepEqual(floor(local(0011, 10, 06, 07)), local(0011, 10, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns sundays": function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 31, 23, 59, 59)), local(2011, 00, 02)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 00)), local(2011, 00, 02)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 01)), local(2011, 00, 02)); - assert.deepEqual(ceil(local(2011, 00, 01, 23, 59, 59)), local(2011, 00, 02)); - assert.deepEqual(ceil(local(2011, 00, 02, 00, 00, 00)), local(2011, 00, 02)); - assert.deepEqual(ceil(local(2011, 00, 02, 00, 00, 01)), local(2011, 00, 09)); - }, - "observes the start of daylight savings time": function(ceil) { - assert.deepEqual(ceil(local(2011, 02, 13, 01)), local(2011, 02, 20)); - }, - "observes the end of the daylight savings time": function(ceil) { - assert.deepEqual(ceil(local(2011, 10, 06, 01)), local(2011, 10, 13)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = local(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, local(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), +1), local(2011, 00, 07, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 456), -2), local(2010, 11, 17, 23, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 01), -1), local(2010, 10, 24)); - assert.deepEqual(offset(local(2011, 00, 01), -2), local(2010, 11, 18)); - assert.deepEqual(offset(local(2011, 00, 01), -1), local(2010, 11, 25)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(local(2010, 10, 24), +1), local(2010, 11, 01)); - assert.deepEqual(offset(local(2010, 11, 18), +2), local(2011, 00, 01)); - assert.deepEqual(offset(local(2010, 11, 25), +1), local(2011, 00, 01)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), 0), local(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58, 000), 0), local(2010, 11, 31, 23, 59, 58, 000)); - } - }, - "UTC": { - topic: function(interval) { - return interval.utc; - }, - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns sundays": function(floor) { - assert.deepEqual(floor(utc(2010, 11, 31, 23, 59, 59)), utc(2010, 11, 26)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 00)), utc(2010, 11, 26)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 01)), utc(2010, 11, 26)); - assert.deepEqual(floor(utc(2011, 00, 01, 23, 59, 59)), utc(2010, 11, 26)); - assert.deepEqual(floor(utc(2011, 00, 02, 00, 00, 00)), utc(2011, 00, 02)); - assert.deepEqual(floor(utc(2011, 00, 02, 00, 00, 01)), utc(2011, 00, 02)); - }, - "does not observe the start of daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 02, 13, 01)), utc(2011, 02, 13)); - }, - "does not observe the end of the daylight savings time": function(floor) { - assert.deepEqual(floor(utc(2011, 10, 06, 01)), utc(2011, 10, 06)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns sundays": function(ceil) { - assert.deepEqual(ceil(utc(2010, 11, 31, 23, 59, 59)), utc(2011, 00, 02)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 00)), utc(2011, 00, 02)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 01)), utc(2011, 00, 02)); - assert.deepEqual(ceil(utc(2011, 00, 01, 23, 59, 59)), utc(2011, 00, 02)); - assert.deepEqual(ceil(utc(2011, 00, 02, 00, 00, 00)), utc(2011, 00, 02)); - assert.deepEqual(ceil(utc(2011, 00, 02, 00, 00, 01)), utc(2011, 00, 09)); - }, - "does not observe the start of daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 02, 13, 01)), utc(2011, 02, 20)); - }, - "does not observe the end of the daylight savings time": function(ceil) { - assert.deepEqual(ceil(utc(2011, 10, 06, 01)), utc(2011, 10, 13)); - } - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = utc(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, utc(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), +1), utc(2011, 00, 07, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 456), -2), utc(2010, 11, 17, 23, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 01), -1), utc(2010, 10, 24)); - assert.deepEqual(offset(utc(2011, 00, 01), -2), utc(2010, 11, 18)); - assert.deepEqual(offset(utc(2011, 00, 01), -1), utc(2010, 11, 25)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 10, 24), +1), utc(2010, 11, 01)); - assert.deepEqual(offset(utc(2010, 11, 18), +2), utc(2011, 00, 01)); - assert.deepEqual(offset(utc(2010, 11, 25), +1), utc(2011, 00, 01)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), 0), utc(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58, 000), 0), utc(2010, 11, 31, 23, 59, 58, 000)); - } - } - } -}); - -suite.export(module); diff --git a/test/time/weeks-test.js b/test/time/weeks-test.js deleted file mode 100644 index 7a110a8db87741..00000000000000 --- a/test/time/weeks-test.js +++ /dev/null @@ -1,95 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"), - time = require("./time"), - local = time.local, - utc = time.utc; - -var suite = vows.describe("d3.time.weeks"); - -suite.addBatch({ - "weeks": { - topic: load("time/week").expression("d3.time.weeks"), - "returns sundays": function(range) { - assert.deepEqual(range(local(2010, 11, 21), local(2011, 0, 12)), [ - local(2010, 11, 26), - local(2011, 0, 2), - local(2011, 0, 9) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(local(2010, 11, 21), local(2011, 0, 12))[0], local(2010, 11, 26)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(local(2010, 11, 21), local(2011, 0, 12))[2], local(2011, 0, 9)); - }, - "can skip weeks": function(range) { - assert.deepEqual(range(local(2011, 0, 1), local(2011, 3, 1), 4), [ - local(2011, 0, 2), - local(2011, 0, 30), - local(2011, 1, 27), - local(2011, 2, 27) - ]); - }, - "observes start of daylight savings time": function(range) { - assert.deepEqual(range(local(2011, 2, 1), local(2011, 2, 28)), [ - local(2011, 2, 6), - local(2011, 2, 13), - local(2011, 2, 20), - local(2011, 2, 27) - ]); - }, - "observes end of daylight savings time": function(range) { - assert.deepEqual(range(local(2011, 10, 1), local(2011, 10, 30)), [ - local(2011, 10, 6), - local(2011, 10, 13), - local(2011, 10, 20), - local(2011, 10, 27) - ]); - }, - "UTC": { - topic: function(range) { - return range.utc; - }, - "returns sundays": function(range) { - assert.deepEqual(range(utc(2010, 11, 21), utc(2011, 0, 12)), [ - utc(2010, 11, 26), - utc(2011, 0, 2), - utc(2011, 0, 9) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 21), utc(2011, 0, 12))[0], utc(2010, 11, 26)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(utc(2010, 11, 21), utc(2011, 0, 12))[2], utc(2011, 0, 9)); - }, - "can skip weeks": function(range) { - assert.deepEqual(range(utc(2011, 0, 1), utc(2011, 3, 1), 4), [ - utc(2011, 0, 2), - utc(2011, 0, 30), - utc(2011, 1, 27), - utc(2011, 2, 27) - ]); - }, - "does not observe the start of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 2, 1), utc(2011, 2, 28)), [ - utc(2011, 2, 6), - utc(2011, 2, 13), - utc(2011, 2, 20), - utc(2011, 2, 27) - ]); - }, - "does not observe the end of daylight savings time": function(range) { - assert.deepEqual(range(utc(2011, 10, 1), utc(2011, 10, 30)), [ - utc(2011, 10, 6), - utc(2011, 10, 13), - utc(2011, 10, 20), - utc(2011, 10, 27) - ]); - } - } - } -}); - -suite.export(module); diff --git a/test/time/year-test.js b/test/time/year-test.js deleted file mode 100644 index 66230f60cba263..00000000000000 --- a/test/time/year-test.js +++ /dev/null @@ -1,137 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.time.year"); - -suite.addBatch({ - "year": { - topic: load("time/year").expression("d3.time.year"), - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns years": function(floor) { - assert.deepEqual(floor(local(2010, 11, 31, 23, 59, 59)), local(2010, 00, 01)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 00)), local(2011, 00, 01)); - assert.deepEqual(floor(local(2011, 00, 01, 00, 00, 01)), local(2011, 00, 01)); - }, - "correctly handles years in the first century": function(floor) { - assert.deepEqual(floor(local(0011, 10, 06, 07)), local(0011, 00, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns years": function(ceil) { - assert.deepEqual(ceil(local(2010, 11, 31, 23, 59, 59)), local(2011, 00, 01)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 00)), local(2011, 00, 01)); - assert.deepEqual(ceil(local(2011, 00, 01, 00, 00, 01)), local(2012, 00, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = local(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, local(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), +1), local(2011, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 456), -2), local(2008, 11, 31, 23, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(local(2010, 11, 01), -1), local(2009, 11, 01)); - assert.deepEqual(offset(local(2011, 00, 01), -2), local(2009, 00, 01)); - assert.deepEqual(offset(local(2011, 00, 01), -1), local(2010, 00, 01)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(local(2009, 11, 01), +1), local(2010, 11, 01)); - assert.deepEqual(offset(local(2009, 00, 01), +2), local(2011, 00, 01)); - assert.deepEqual(offset(local(2010, 00, 01), +1), local(2011, 00, 01)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 59, 999), 0), local(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(local(2010, 11, 31, 23, 59, 58, 000), 0), local(2010, 11, 31, 23, 59, 58, 000)); - } - }, - "UTC": { - topic: function(interval) { - return interval.utc; - }, - "defaults to floor": function(interval) { - assert.strictEqual(interval, interval.floor); - }, - "floor": { - topic: function(interval) { - return interval.floor; - }, - "returns years": function(floor) { - assert.deepEqual(floor(utc(2010, 11, 31, 23, 59, 59)), utc(2010, 00, 01)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 00)), utc(2011, 00, 01)); - assert.deepEqual(floor(utc(2011, 00, 01, 00, 00, 01)), utc(2011, 00, 01)); - } - }, - "ceil": { - topic: function(interval) { - return interval.ceil; - }, - "returns years": function(ceil) { - assert.deepEqual(ceil(utc(2010, 11, 31, 23, 59, 59)), utc(2011, 00, 01)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 00)), utc(2011, 00, 01)); - assert.deepEqual(ceil(utc(2011, 00, 01, 00, 00, 01)), utc(2012, 00, 01)); - } - }, - "offset": { - topic: function(interval) { - return interval.offset; - }, - "does not modify the passed-in date": function(offset) { - var date = utc(2010, 11, 31, 23, 59, 59, 999); - offset(date, +1); - assert.deepEqual(date, utc(2010, 11, 31, 23, 59, 59, 999)); - }, - "does not round the passed-in-date": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), +1), utc(2011, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 456), -2), utc(2008, 11, 31, 23, 59, 59, 456)); - }, - "allows negative offsets": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 01), -1), utc(2009, 11, 01)); - assert.deepEqual(offset(utc(2011, 00, 01), -2), utc(2009, 00, 01)); - assert.deepEqual(offset(utc(2011, 00, 01), -1), utc(2010, 00, 01)); - }, - "allows positive offsets": function(offset) { - assert.deepEqual(offset(utc(2009, 11, 01), +1), utc(2010, 11, 01)); - assert.deepEqual(offset(utc(2009, 00, 01), +2), utc(2011, 00, 01)); - assert.deepEqual(offset(utc(2010, 00, 01), +1), utc(2011, 00, 01)); - }, - "allows zero offset": function(offset) { - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 59, 999), 0), utc(2010, 11, 31, 23, 59, 59, 999)); - assert.deepEqual(offset(utc(2010, 11, 31, 23, 59, 58, 000), 0), utc(2010, 11, 31, 23, 59, 58, 000)); - } - } - } - } -}); - -function local(year, month, day, hours, minutes, seconds, milliseconds) { - var date = new Date(); - date.setFullYear(year, month, day); - date.setHours(hours || 0, minutes || 0, seconds || 0, milliseconds || 0); - return date; -} - -function utc(year, month, day, hours, minutes, seconds, milliseconds) { - var date = new Date(); - date.setUTCFullYear(year, month, day); - date.setUTCHours(hours || 0, minutes || 0, seconds || 0, milliseconds || 0); - return date; -} - -suite.export(module); diff --git a/test/time/years-test.js b/test/time/years-test.js deleted file mode 100644 index 16f61410788bd5..00000000000000 --- a/test/time/years-test.js +++ /dev/null @@ -1,74 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.time.years"); - -suite.addBatch({ - "years": { - topic: load("time/year").expression("d3.time.years"), - "returns years": function(range) { - assert.deepEqual(range(local(2010, 0, 1), local(2013, 0, 1)), [ - local(2010, 0, 1), - local(2011, 0, 1), - local(2012, 0, 1) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(local(2010, 0, 1), local(2013, 0, 1))[0], local(2010, 0, 1)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(local(2010, 0, 1), local(2013, 0, 1))[2], local(2012, 0, 1)); - }, - "can skip years": function(range) { - assert.deepEqual(range(local(2009, 0, 1), local(2029, 0, 1), 5), [ - local(2010, 0, 1), - local(2015, 0, 1), - local(2020, 0, 1), - local(2025, 0, 1) - ]); - }, - "UTC": { - topic: function(range) { - return range.utc; - }, - "returns years": function(range) { - assert.deepEqual(range(utc(2010, 0, 1), utc(2013, 0, 1)), [ - utc(2010, 0, 1), - utc(2011, 0, 1), - utc(2012, 0, 1) - ]); - }, - "has an inclusive lower bound": function(range) { - assert.deepEqual(range(utc(2010, 0, 1), utc(2013, 0, 1))[0], utc(2010, 0, 1)); - }, - "has an exclusive upper bound": function(range) { - assert.deepEqual(range(utc(2010, 0, 1), utc(2013, 0, 1))[2], utc(2012, 0, 1)); - }, - "can skip years": function(range) { - assert.deepEqual(range(utc(2009, 0, 1), utc(2029, 0, 1), 5), [ - utc(2010, 0, 1), - utc(2015, 0, 1), - utc(2020, 0, 1), - utc(2025, 0, 1) - ]); - } - } - } -}); - -function local(year, month, day, hours, minutes, seconds, milliseconds) { - var date = new Date(); - date.setFullYear(year, month, day); - date.setHours(hours || 0, minutes || 0, seconds || 0, milliseconds || 0); - return date; -} - -function utc(year, month, day, hours, minutes, seconds, milliseconds) { - var date = new Date(); - date.setUTCFullYear(year, month, day); - date.setUTCHours(hours || 0, minutes || 0, seconds || 0, milliseconds || 0); - return date; -} - -suite.export(module); diff --git a/test/transition/transition-test-attr.js b/test/transition/transition-test-attr.js deleted file mode 100644 index 627f91792f14d1..00000000000000 --- a/test/transition/transition-test-attr.js +++ /dev/null @@ -1,56 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - var s = d3.select("body").append("div") - .attr("display", "none") - .attr("font-size", "20px") - .attr("width", 20) - .attr("color", "red") - .attr("xlink:type", "simple") - .attr("xlink:href", "http://mbostock.github.com/d3/"); - - var t = s.transition() - .attr("display", null) - .attr("font-size", function() { return null; }) - .attr("display", null) - .attr("width", 100) - .attr("width", 200) - .attr("color", function() { return "green"; }) - .attr("xlink:href", null) - .attr("xlink:type", function() { return null; }); - - return {selection: s, transition: t}; - }, - "defines the corresponding attr tween": function(result) { - assert.typeOf(result.transition.tween("attr.width"), "function"); - assert.typeOf(result.transition.tween("attr.color"), "function"); - }, - "on end": { - topic: function(result) { - var cb = this.callback; - result.transition.each("end", function() { cb(null, result); }); - }, - "the last attr operator takes precedence": function(result) { - assert.equal(result.selection.attr("width"), "200"); - }, - "sets an attribute as a number": function(result) { - assert.equal(result.selection.attr("width"), "200"); - }, - "sets an attribute as a function": function(result) { - assert.equal(result.selection.attr("color"), "#008000"); - }, - "removes an attribute using a constant null": function(result) { - assert.isNull(result.selection.attr("display")); - }, - "removes an attribute using a function null": function(result) { - assert.isNull(result.selection.attr("font-size")); - }, - "removes a namespaced attribute using a constant null": function(result) { - assert.isNull(result.selection.attr("xlink:href")); - }, - "removes a namespaced attribute using a function null": function(result) { - assert.isNull(result.selection.attr("xlink:type")); - } - } -}; diff --git a/test/transition/transition-test-attrTween.js b/test/transition/transition-test-attrTween.js deleted file mode 100644 index 5bd4b33e1b052e..00000000000000 --- a/test/transition/transition-test-attrTween.js +++ /dev/null @@ -1,59 +0,0 @@ -var assert = require("../assert"), - _ = require("../../"); - -module.exports = { - topic: function(d3) { - var callback = this.callback, - dd = [], - ii = [], - tt = [], - vv = []; - - var s = d3.select("body").html("").append("div").selectAll("div") - .data(["red", "green"]) - .enter().append("div") - .attr("color", function(d, i) { return i ? "#008000" : "#ff0000"; }); - - var t = s.transition() - .attrTween("color", tween); - - function tween(d, i, v) { - dd.push(d); - ii.push(i); - vv.push(v); - if (tt.push(this) >= 2) callback(null, { - selection: s, - transition: t, - data: dd, - index: ii, - value: vv, - context: tt - }); - return i && _.interpolateHsl(v, "blue"); - } - }, - - "defines the corresponding attr tween": function(result) { - assert.typeOf(result.transition.tween("attr.color"), "function"); - }, - "invokes the tween function": function(result) { - assert.deepEqual(result.data, ["red", "green"], "expected data, got {actual}"); - assert.deepEqual(result.index, [0, 1], "expected data, got {actual}"); - assert.deepEqual(result.value, ["#ff0000", "#008000"], "expected value, got {actual}"); - assert.domEqual(result.context[0], result.selection[0][0], "expected this, got {actual}"); - assert.domEqual(result.context[1], result.selection[0][1], "expected this, got {actual}"); - }, - - "end": { - topic: function(result) { - var callback = this.callback; - result.transition.each("end", function(d, i) { if (i >= 1) callback(null, result); }); - }, - "uses the returned interpolator": function(result) { - assert.equal(result.selection[0][1].getAttribute("color"), "#0000ff"); - }, - "does nothing if the interpolator is falsey": function(result) { - assert.equal(result.selection[0][0].getAttribute("color"), "#ff0000"); - } - } -}; diff --git a/test/transition/transition-test-call.js b/test/transition/transition-test-call.js deleted file mode 100644 index 816d26e1604bc4..00000000000000 --- a/test/transition/transition-test-call.js +++ /dev/null @@ -1,30 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - return d3.select("body").append("div").transition(); - }, - "calls the function once": function(transition) { - var count = 0; - transition.call(function() { ++count; }); - assert.equal(count, 1); - }, - "passes any optional arguments": function(transition) { - var abc; - transition.call(function(selection, a, b, c) { abc = [a, b, c]; }, "a", "b", "c"); - assert.deepEqual(abc, ["a", "b", "c"]); - }, - "passes the transition as the first argument": function(transition) { - var t; - transition.call(function(x) { t = x; }); - assert.isTrue(t === transition); - }, - "uses the transition as the context": function(transition) { - var t; - transition.call(function() { t = this; }); - assert.isTrue(t === transition); - }, - "returns the current transition": function(transition) { - assert.isTrue(transition.call(function() {}) === transition); - } -}; diff --git a/test/transition/transition-test-delay.js b/test/transition/transition-test-delay.js deleted file mode 100644 index e721c3619e13e6..00000000000000 --- a/test/transition/transition-test-delay.js +++ /dev/null @@ -1,56 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - return d3.select("body").html("").selectAll() - .data(["foo", "bar"]) - .enter().append("div") - .attr("class", String); - }, - "defaults to zero": function(selection) { - var t = selection.transition(); - assert.strictEqual(t[0][0].__transition__[t.id].delay, 0); - assert.strictEqual(t[0][1].__transition__[t.id].delay, 0); - }, - "can specify delay as a number": function(selection) { - var t = selection.transition().delay(150); - assert.strictEqual(t[0][0].__transition__[t.id].delay, 150); - assert.strictEqual(t[0][1].__transition__[t.id].delay, 150); - t.delay(250); - assert.strictEqual(t[0][0].__transition__[t.id].delay, 250); - assert.strictEqual(t[0][1].__transition__[t.id].delay, 250); - }, - "can specify delay as a negative number": function(selection) { - var t = selection.transition().delay(-250); - assert.strictEqual(t[0][0].__transition__[t.id].delay, -250); - assert.strictEqual(t[0][1].__transition__[t.id].delay, -250); - }, - "delay is coerced to a number": function(selection) { - var t = selection.transition().delay("520"); - assert.strictEqual(t[0][0].__transition__[t.id].delay, 520); - assert.strictEqual(t[0][1].__transition__[t.id].delay, 520); - }, - "floating-point durations are not floored to integers": function(selection) { - var t = selection.transition().delay(14.6); - assert.strictEqual(t[0][0].__transition__[t.id].delay, 14.6); - assert.strictEqual(t[0][1].__transition__[t.id].delay, 14.6); - var t = selection.transition().delay("16.99"); - assert.strictEqual(t[0][0].__transition__[t.id].delay, 16.99); - assert.strictEqual(t[0][1].__transition__[t.id].delay, 16.99); - }, - "can specify delay as a function": function(selection) { - var dd = [], ii = [], tt = [], t = selection.transition().delay(f); - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return i * 20; } - assert.strictEqual(t[0][0].__transition__[t.id].delay, 0); - assert.strictEqual(t[0][1].__transition__[t.id].delay, 20); - assert.deepEqual(dd, ["foo", "bar"], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.domEqual(tt[0], t[0][0], "expected this, got {actual}"); - assert.domEqual(tt[1], t[0][1], "expected this, got {actual}"); - }, - "coerces delay to a number": function(selection) { - var t = selection.transition().delay("150"); - assert.strictEqual(t[0][0].__transition__[t.id].delay, 150); - assert.strictEqual(t[0][1].__transition__[t.id].delay, 150); - } -}; diff --git a/test/transition/transition-test-duration.js b/test/transition/transition-test-duration.js deleted file mode 100644 index 34fc2dc6de85c1..00000000000000 --- a/test/transition/transition-test-duration.js +++ /dev/null @@ -1,62 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - return d3.select("body").html("").selectAll() - .data(["foo", "bar"]) - .enter().append("div") - .attr("class", String); - }, - "defaults to 250 milliseconds": function(selection) { - var t = selection.transition(); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 250); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 250); - }, - "can specify duration as a number": function(selection) { - var t = selection.transition().duration(150); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 150); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 150); - t.duration(50); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 50); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 50); - }, - "zero or negative durations are treated as 1ms": function(selection) { - var t = selection.transition().duration(0); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 1); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 1); - t.duration(-10); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 1); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 1); - t.duration(-Infinity); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 1); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 1); - }, - "duration is coerced to a number": function(selection) { - var t = selection.transition().duration("520"); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 520); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 520); - }, - "floating-point durations are not floored to integers": function(selection) { - var t = selection.transition().duration(14.6); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 14.6); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 14.6); - var t = selection.transition().duration("16.99"); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 16.99); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 16.99); - }, - "can specify duration as a function": function(selection) { - var dd = [], ii = [], tt = [], t = selection.transition().duration(f); - function f(d, i) { dd.push(d); ii.push(i); tt.push(this); return i * 20 + 10; } - assert.strictEqual(t[0][0].__transition__[t.id].duration, 10); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 30); - assert.deepEqual(dd, ["foo", "bar"], "expected data, got {actual}"); - assert.deepEqual(ii, [0, 1], "expected index, got {actual}"); - assert.domEqual(tt[0], t[0][0], "expected this, got {actual}"); - assert.domEqual(tt[1], t[0][1], "expected this, got {actual}"); - }, - "coerces duration to a number": function(selection) { - var t = selection.transition().duration("150"); - assert.strictEqual(t[0][0].__transition__[t.id].duration, 150); - assert.strictEqual(t[0][1].__transition__[t.id].duration, 150); - } -}; diff --git a/test/transition/transition-test-each.js b/test/transition/transition-test-each.js deleted file mode 100644 index 0b652064b1a562..00000000000000 --- a/test/transition/transition-test-each.js +++ /dev/null @@ -1,171 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - "start": { - topic: function(d3) { - var callback = this.callback, - div = d3.select("body").html("").selectAll().data(["foo", "bar"]).enter().append("div").attr("class", String), - transition = div.transition().delay(350), - then = Date.now(), - n = 0, - calls = [], - context = [], - data = [], - index = [], - count = [], - delay = []; - - // A callback to verify that multiple callbacks are allowed. - transition.each("start.other", function() { - ++n; - }); - - // A callback which captures arguments and context. - transition.each("start", function(d, i) { - context.push(this); - data.push(d); - index.push(i); - count.push(++n); - delay.push(Date.now() - then); - if (n >= 4) callback(null, { - selection: div, - delay: delay, - context: context, - data: data, - index: index, - count: count, - id: transition.id - }); - }); - }, - - "invokes the listener after the specified delay": function(result) { - assert.inDelta(result.delay, [350, 350], 20); - }, - "invokes each listener exactly once, in order": function(result) { - assert.deepEqual(result.count, [2, 4]); - }, - - // For the same node, listeners will be called back in order, according to - // the implementation of d3.dispatch. However, the order of callbacks across - // nodes is not guaranteed; currently, callbacks are in reverse order if - // they share the same delay, because of the timer queue. I suppose it'd be - // slightly better if the callbacks were invoked in node order (consistent - // with selections), but since these callbacks happen asynchronously I don't - // think the API needs to guarantee the order of callbacks. - - "uses the node as the context": function(result) { - assert.domEqual(result.context[0], result.selection[0][0]); - assert.domEqual(result.context[1], result.selection[0][1]); - }, - "passes the data and index to the function": function(result) { - assert.deepEqual(result.data, ["foo", "bar"], "expected data, got {actual}"); - assert.deepEqual(result.index, [0, 1], "expected index, got {actual}"); - }, - - "sets an exclusive lock on transitioning nodes": function(result) { - var id = result.id; - assert.isTrue(id > 0); - assert.equal(result.selection[0][0].__transition__.count, 1); - assert.equal(result.selection[0][1].__transition__.count, 1); - assert.equal(result.selection[0][0].__transition__.active, id); - assert.equal(result.selection[0][1].__transition__.active, id); - } - }, - - "end": { - topic: function(d3) { - var callback = this.callback, - div = d3.select("body").html("").selectAll().data(["foo", "bar"]).enter().append("div").attr("class", String), - transition = div.transition().duration(350), - then = Date.now(), - n = 0, - calls = [], - context = [], - data = [], - index = [], - count = [], - delay = []; - - // A callback to verify that multiple callbacks are allowed. - transition.each("end.other", function() { - ++n; - }); - - // A callback which captures arguments and context. - transition.each("end", function(d, i) { - context.push(this); - data.push(d); - index.push(i); - count.push(++n); - delay.push(Date.now() - then); - if (n >= 4) callback(null, { - selection: div, - delay: delay, - context: context, - data: data, - index: index, - count: count, - id: transition.id - }); - }); - }, - - "invokes the listener after the specified delay": function(result) { - assert.inDelta(result.delay, [350, 350], 20); - }, - "invokes each listener exactly once, in order": function(result) { - assert.deepEqual(result.count, [2, 4]); - }, - - // For the same node, listeners will be called back in order, according to - // the implementation of d3.dispatch. However, the order of callbacks across - // nodes is not guaranteed; currently, callbacks are in reverse order if - // they share the same delay, because of the timer queue. I suppose it'd be - // slightly better if the callbacks were invoked in node order (consistent - // with selections), but since these callbacks happen asynchronously I don't - // think the API needs to guarantee the order of callbacks. - - "uses the node as the context": function(result) { - assert.domEqual(result.context[0], result.selection[0][0]); - assert.domEqual(result.context[1], result.selection[0][1]); - }, - "passes the data and index to the function": function(result) { - assert.deepEqual(result.data, ["foo", "bar"], "expected data, got {actual}"); - assert.deepEqual(result.index, [0, 1], "expected index, got {actual}"); - }, - - "after the transition ends": { - topic: function(result) { - var callback = this.callback; - process.nextTick(function() { - callback(null, result); - }); - }, - "deletes the transition lock": function(result) { - assert.isFalse("__transition__" in result.selection[0][0]); - assert.isFalse("__transition__" in result.selection[0][1]); - } - }, - - // I'd like to test d3.timer.flush here, but unfortunately there's a bug in - // Vows where it really doesn't like to receive multiple callbacks from - // different tests at the same time! - - "sequenced": { - topic: function(result, d3) { - var callback = this.callback, - node = d3.select("body").append("div").node(), - id = result.id; - d3.select(node).transition().delay(150).each("start", function() { - callback(null, {id: id, node: this}); - }); - }, - "does not inherit the transition id": function(result) { - assert.isTrue(result.id > 0); - assert.equal(result.node.__transition__.count, 1); - assert.isTrue(result.node.__transition__.active > result.id); - } - } - } -}; diff --git a/test/transition/transition-test-filter.js b/test/transition/transition-test-filter.js deleted file mode 100644 index 9667d5c22a1b10..00000000000000 --- a/test/transition/transition-test-filter.js +++ /dev/null @@ -1,80 +0,0 @@ -var assert = require("../assert"), - _ = require("../../"); - -var datum = {}; - -module.exports = { - topic: function(d3) { - return d3.select("body").html("").selectAll("div") - .data([0, 1]) - .enter().append("div") - .selectAll("span") - .data(function(d) { d <<= 1; return [d, d + 1]; }) - .enter().append("span") - .classed("foo", function(d, i) { return d & 1; }) - .transition() - .delay(100) - .duration(150) - .ease("bounce"); - }, - - "preserves matching elements": function(span) { - var some = span.filter(function(d, i) { return i === 0; }); - assert.isTrue(some[0][0] === span[0][0]); - assert.isTrue(some[1][0] === span[1][0]); - }, - "removes non-matching elements": function(span) { - var some = _.merge(span.filter(function(d, i) { return d & 1; })); - assert.equal(some.indexOf(span[0][0]), -1); - assert.equal(some.indexOf(span[1][0]), -1); - }, - "preserves data": function(span) { - var some = span.filter(function(d, i) { return d & 1; }); - assert.equal(some[0][0].__data__, 1); - assert.equal(some[1][0].__data__, 3); - }, - "preserves grouping": function(span) { - var some = span.filter(function(d, i) { return d & 1; }); - assert.equal(some.length, 2); - assert.equal(some[0].length, 1); - assert.equal(some[1].length, 1); - }, - "preserves parent node": function(span) { - var some = span.filter(function(d, i) { return d & 1; }); - assert.isTrue(some[0].parentNode === span[0].parentNode); - assert.isTrue(some[1].parentNode === span[1].parentNode); - }, - "does not preserve index": function(span) { - var indexes = []; - span.filter(function(d, i) { return d & 1; }).each(function(d, i) { indexes.push(i); }); - assert.deepEqual(indexes, [0, 0]); - }, - "ignores null nodes": function(span) { - var node = span[0][1]; - span[0][1] = null; - var some = span.filter(function(d, i) { return d & 1; }); - assert.isTrue(some[0][0] === span[0][3]); - assert.equal(some.length, 2); - span[0][1] = node; - }, - "can be specified as a selector": function(span) { - var some = span.filter(".foo"); - assert.equal(some.length, 2); - assert.equal(some[0].length, 1); - assert.equal(some[1].length, 1); - }, - "returns a new selection": function(span) { - assert.isFalse(span.filter(function() { return 1; }) === span); - }, - "works on empty selections": function(span) { - var none = function() { return false; }, - empty = span.filter(none); - assert.isTrue(empty.empty()); - assert.isTrue(empty.filter(none).empty()); - }, - "inherits the transition id and, by extension, all transition parameters": function(t1) { - var t2 = t1.filter(function() { return 1; }); - assert.equal(t2.id, t1.id); - assert.strictEqual(t2[0][0].__transition__[t2.id], t1[0][0].__transition__[t1.id]); - } -}; diff --git a/test/transition/transition-test-id.js b/test/transition/transition-test-id.js deleted file mode 100644 index 858a230f31ee84..00000000000000 --- a/test/transition/transition-test-id.js +++ /dev/null @@ -1,22 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - return d3; // bug in vows where topic is not propagated automatically - }, - "on a new transition": { - topic: function(d3) { - return d3.select("body").append("div").transition(); - }, - "has a positive integer id": function(transition) { - var id = transition.id; - assert.isTrue(id > 0); - assert.equal(~~id, id); - } - }, - "increases monotonically across transitions": function(d3) { - var t0 = d3.select("body").append("div").transition(), - t1 = d3.select("body").append("div").transition(); - assert.isTrue(t1.id > t0.id); - } -}; diff --git a/test/transition/transition-test-node.js b/test/transition/transition-test-node.js deleted file mode 100644 index 54d13d940af003..00000000000000 --- a/test/transition/transition-test-node.js +++ /dev/null @@ -1,39 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - "with a single element selected": { - topic: function(d3) { - return d3.select("body").transition(); - }, - "returns null for empty subselections": function(body) { - assert.isNull(body.select("foo").node()); - }, - "returns the selected element": function(body) { - assert.equal(body.node().tagName, "BODY"); - }, - "returns null if no elements are slected": function(body) { - body[0][0] = null; - assert.isNull(body.node()); - } - }, - "with multiple elements selected": { - topic: function(d3) { - var body = d3.select("body").html(null); - body.append("div").attr("class", "first").append("span"); - body.append("div").attr("class", "second"); - return body.selectAll("div").transition(); - }, - "returns null for empty subselections": function(div) { - assert.isNull(div.select("foo").node()); - }, - "returns the first selected element": function(div) { - assert.equal(div.node().className, "first"); - assert.equal(div.node().tagName, "DIV"); - }, - "does not count null nodes": function(div) { - div[0][0] = null; - assert.equal(div.node().className, "second"); - assert.equal(div.node().tagName, "DIV"); - } - } -}; diff --git a/test/transition/transition-test-remove.js b/test/transition/transition-test-remove.js deleted file mode 100644 index fcf98c53b7fb4e..00000000000000 --- a/test/transition/transition-test-remove.js +++ /dev/null @@ -1,57 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - "on a new transition": { - topic: function(d3) { - var callback = this.callback, - t = d3.select("body").append("div").transition().remove(); - t.each("end", function() { - process.nextTick(function() { - callback(null, t); - }); - }); - }, - "removes the selected elements": function(transition) { - assert.domEqual(transition[0][0].parentNode, null); - } - }, - - "when the element is already removed": { - topic: function(d3) { - var callback = this.callback, - t = d3.select("body").append("div").remove().transition().remove(); - t.each("end", function() { - process.nextTick(function() { - callback(null, t); - }); - }); - }, - "does nothing": function(transition) { - assert.domEqual(transition[0][0].parentNode, null); - } - }, - - // Since these tests are triggered inside the end event of the above topic, - // transitions will inherit ids from the original transition. But we want to - // test concurrent transitions, so we use timeouts to avoid inheritance. This - // test also verifies that if multiple transitions are created at the same - // time, the last transition becomes the owner. - - "when another transition is scheduled": { - topic: function(d3) { - var callback = this.callback, - s = d3.select("body").append("div"); - setTimeout(function() { - s.transition().duration(150).remove().each("end", function() { - process.nextTick(function() { - callback(null, s); - }); - }); - s.transition().delay(250); - }, 10); - }, - "does nothing": function(selection) { - assert.equal(selection[0][0].parentNode.tagName, "BODY"); - } - } -}; diff --git a/test/transition/transition-test-select.js b/test/transition/transition-test-select.js deleted file mode 100644 index cf8b148ca5a310..00000000000000 --- a/test/transition/transition-test-select.js +++ /dev/null @@ -1,60 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - var s = d3.select("body").append("div").selectAll("div") - .data(["one", "two", "three", "four"]) - .enter().append("div") - .attr("class", String); - - s.filter(function(d, i) { return i > 0; }).append("span"); - s[0][3] = null; - - return s.transition() - .delay(function(d, i) { return i * 13; }) - .duration(function(d, i) { return i * 21; }); - }, - - "selects the first matching element": function(transition) { - var t = transition.select("span"); - assert.domEqual(t[0][1].parentNode, transition[0][1]); - assert.domEqual(t[0][2].parentNode, transition[0][2]); - }, - "ignores null elements": function(transition) { - var t = transition.select("span"); - assert.isNull(t[0][3]); - }, - "propagates data to the selected elements": function(transition) { - var t = transition.select("span"); - assert.equal(t[0][1].__data__, "two"); - assert.equal(t[0][2].__data__, "three"); - }, - "propagates delay to the selected elements": function(transition) { - var t = transition.select("span"); - assert.equal(t[0][1].__transition__[t.id].delay, 13); - assert.equal(t[0][2].__transition__[t.id].delay, 26); - }, - "propagates duration to the selected elements": function(transition) { - var t = transition.select("span"); - assert.equal(t[0][1].__transition__[t.id].duration, 21); - assert.equal(t[0][2].__transition__[t.id].duration, 42); - }, - "does not propagate data if no data was specified": function(transition) { - delete transition[0][1].__data__; - delete transition[0][1].firstChild.__data__; - var t = transition.select("span"); - assert.isUndefined(t[0][1].__data__); - assert.equal(t[0][2].__data__, "three"); - }, - "returns null if no match is found": function(transition) { - var t = transition.select("span"); - assert.isNull(t[0][0]); - }, - "inherits transition id": function(transition) { - var id = transition.id, - t0 = transition.select("span"), - t1 = transition.select("span"); - assert.equal(t0.id, id); - assert.equal(t1.id, id); - } -}; diff --git a/test/transition/transition-test-selectAll.js b/test/transition/transition-test-selectAll.js deleted file mode 100644 index 2450c565a09017..00000000000000 --- a/test/transition/transition-test-selectAll.js +++ /dev/null @@ -1,56 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - var s = d3.select("body").append("div").selectAll("div") - .data(["one", "two", "three", "four"]) - .enter().append("div") - .attr("class", String); - - s.filter(function(d, i) { return i > 0; }).append("span"); - s.filter(function(d, i) { return i > 1; }).append("span"); - s[0][3] = null; - - return s.transition() - .delay(function(d, i) { return i * 13; }) - .duration(function(d, i) { return i * 21; }); - }, - - "selects all matching elements": function(transition) { - var t = transition.selectAll("span"); - assert.domEqual(t[1][0].parentNode, transition[0][1]); - assert.domEqual(t[2][0].parentNode, transition[0][2]); - assert.domEqual(t[2][1].parentNode, transition[0][2]); - }, - "ignores null elements": function(transition) { - var t = transition.selectAll("span"); - assert.equal(t.length, 3); - }, - "propagates delay to the selected elements": function(transition) { - var t = transition.selectAll("span"); - assert.domEqual(t[1][0].__transition__[t.id].delay, 13); - assert.domEqual(t[2][0].__transition__[t.id].delay, 26); - assert.domEqual(t[2][1].__transition__[t.id].delay, 26); - }, - "propagates duration to the selected elements": function(transition) { - var t = transition.selectAll("span"); - assert.domEqual(t[1][0].__transition__[t.id].duration, 21); - assert.domEqual(t[2][0].__transition__[t.id].duration, 42); - assert.domEqual(t[2][1].__transition__[t.id].duration, 42); - }, - "returns empty if no match is found": function(transition) { - var t = transition.selectAll("span"); - assert.isEmpty(t[0]); - }, - "inherits transition id": function(transition) { - var id = transition.id, - t0 = transition.selectAll("span"), - t1 = transition.selectAll("span"); - assert.equal(t0.id, id); - assert.equal(t1.id, id); - }, - "groups are arrays, not instances of NodeList": function(transition) { - var t = transition.selectAll(function() { return this.getElementsByClassName("span"); }); - assert.isTrue(Array.isArray(t[0])); - } -}; diff --git a/test/transition/transition-test-size.js b/test/transition/transition-test-size.js deleted file mode 100644 index 60f6615f7ffff0..00000000000000 --- a/test/transition/transition-test-size.js +++ /dev/null @@ -1,37 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - "with a single element selected": { - topic: function(d3) { - return d3.select("body").transition(); - }, - "returns zero for empty subselections": function(body) { - assert.equal(body.select("foo").size(), 0); - }, - "returns one for a singleton selection": function(body) { - assert.equal(body.size(), 1); - }, - "does not count null nodes": function(body) { - body[0][0] = null; - assert.equal(body.size(), 0); - } - }, - "with multiple elements selected": { - topic: function(d3) { - var body = d3.select("body").html(null); - body.append("div").append("span"); - body.append("div"); - return body.selectAll("div").transition(); - }, - "returns null for empty selections": function(div) { - assert.equal(div.select("foo").size(), 0); - }, - "returns the number of non-null nodes": function(div) { - assert.equal(div.size(), 2); - }, - "does not count null nodes": function(div) { - div[0][0] = null; - assert.equal(div.size(), 1); - } - } -}; diff --git a/test/transition/transition-test-style.js b/test/transition/transition-test-style.js deleted file mode 100644 index 9380764dd55280..00000000000000 --- a/test/transition/transition-test-style.js +++ /dev/null @@ -1,51 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - var s = d3.select("body").append("div") - .style("background-color", "white") - .style("color", "red") - .style("display", "none") - .style("font-size", "20px"); - - var t = s.transition() - .style("display", null) - .style("font-size", function() { return null; }) - .style("display", null) - .style("background-color", "green") - .style("background-color", "red") - .style("color", function() { return "green"; }, "important"); - - return {selection: s, transition: t}; - }, - "defines the corresponding style tween": function(result) { - assert.typeOf(result.transition.tween("style.background-color"), "function"); - assert.typeOf(result.transition.tween("style.color"), "function"); - }, - "on end": { - topic: function(result) { - var cb = this.callback; - result.transition.each("end", function() { cb(null, result); }); - }, - "the last style operator takes precedence": function(result) { - assert.equal(result.selection.style("background-color"), "#ff0000"); - }, - "sets a property as a string": function(result) { - assert.equal(result.selection.style("background-color"), "#ff0000"); - }, - "sets a property as a function": function(result) { - assert.equal(result.selection.style("color"), "#008000"); - }, - "observes the specified priority": function(result) { - var style = result.selection.node().style; - assert.equal(style.getPropertyPriority("background-color"), ""); - assert.equal(style.getPropertyPriority("color"), "important"); - }, - "removes a property using a constant null": function(result) { - assert.equal(result.selection.style("display"), ""); - }, - "removes a property using a function null": function(result) { - assert.equal(result.selection.style("font-size"), ""); - } - } -}; diff --git a/test/transition/transition-test-styleTween.js b/test/transition/transition-test-styleTween.js deleted file mode 100644 index 361857803dad8e..00000000000000 --- a/test/transition/transition-test-styleTween.js +++ /dev/null @@ -1,65 +0,0 @@ -var assert = require("../assert"), - _ = require("../../"); - -module.exports = { - topic: function(d3) { - var cb = this.callback, - dd = [], - ii = [], - tt = [], - vv = [], - fails = 0; - - var s = d3.select("body").html("").append("div").selectAll("div") - .data(["red", "green"]) - .enter().append("div") - .style("background-color", function(d) { return d3.rgb(d)+""; }); - - var t = s.transition() - .styleTween("background-color", function() { ++fails; }) - .styleTween("background-color", tween); - - function tween(d, i, v) { - dd.push(d); - ii.push(i); - vv.push(v); - if (tt.push(this) >= 2) cb(null, { - selection: s, - transition: t, - data: dd, - index: ii, - value: vv, - context: tt, - fails: fails - }); - return i && _.interpolateHsl(v, "blue"); - } - }, - - "defines the corresponding style tween": function(result) { - assert.typeOf(result.transition.tween("style.background-color"), "function"); - }, - "the last style tween takes precedence": function(result) { - assert.equal(result.fails, 0); - }, - "invokes the tween function": function(result) { - assert.deepEqual(result.data, ["red", "green"], "expected data, got {actual}"); - assert.deepEqual(result.index, [0, 1], "expected index, got {actual}"); - assert.deepEqual(result.value, ["#ff0000", "#008000"], "expected value, got {actual}"); - assert.domEqual(result.context[0], result.selection[0][0], "expected this, got {actual}"); - assert.domEqual(result.context[1], result.selection[0][1], "expected this, got {actual}"); - }, - - "end": { - topic: function(result) { - var cb = this.callback; - result.transition.each("end", function(d, i) { if (i >= 1) cb(null, result); }); - }, - "uses the returned interpolator": function(result) { - assert.equal(result.selection[0][1].style.getPropertyValue("background-color"), "#0000ff"); - }, - "does nothing if the interpolator is falsey": function(result) { - assert.equal(result.selection[0][0].style.getPropertyValue("background-color"), "#ff0000"); - } - } -}; diff --git a/test/transition/transition-test-text.js b/test/transition/transition-test-text.js deleted file mode 100644 index b755bf64a7e98d..00000000000000 --- a/test/transition/transition-test-text.js +++ /dev/null @@ -1,27 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - return d3.select("body").append("div").text("foo").transition().text("bar"); - }, - "sets the text tween": function(div) { - assert.typeOf(div.tween("text"), "function"); - }, - "start": { - topic: function(div) { - var cb = this.callback, - tween = div.tween("text"); - div.tween("text", function() { - var result = tween.apply(this, arguments); - cb(null, {transition: div, tween: result}); - return result; - }); - }, - "sets the text content as a string": function(result) { - assert.equal(result.transition[0][0].textContent, "bar"); - }, - "does not interpolate text": function(result) { - assert.isTrue(!result.tween); - } - } -}; diff --git a/test/transition/transition-test-time.js b/test/transition/transition-test-time.js deleted file mode 100644 index f982a807ab50a7..00000000000000 --- a/test/transition/transition-test-time.js +++ /dev/null @@ -1,38 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - return d3; // bug in vows where topic is not propagated automatically - }, - "on a new transition": { - topic: function(d3) { - return d3.select("body").append("div").transition(); - }, - "is approximately equal to now": function(transition) { - var time = transition[0][0].__transition__[transition.id].time; - assert.inDelta(time, Date.now(), 20); - } - }, - "increases monotonically across transitions": function(d3) { - var now = Date.now, then = Date.now(); - try { - Date.now = function() { return ++then; }; - var t0 = d3.select("body").append("div").transition(), - t1 = d3.select("body").append("div").transition(); - assert.isTrue(t1[0][0].__transition__[t1.id].time > t0[0][0].__transition__[t0.id].time); - } finally { - Date.now = now; - } - }, - "is inherited by subtransitions": function(d3) { - var now = Date.now, then = Date.now(); - try { - Date.now = function() { return ++then; }; - var t0 = d3.select("body").append("div").transition(), - t1 = t0.transition(); - assert.equal(t1[0][0].__transition__[t1.id].time, t0[0][0].__transition__[t0.id].time); - } finally { - Date.now = now; - } - } -}; diff --git a/test/transition/transition-test-transition.js b/test/transition/transition-test-transition.js deleted file mode 100644 index c2109e7656c751..00000000000000 --- a/test/transition/transition-test-transition.js +++ /dev/null @@ -1,59 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - return d3.select("body").append("div").transition() - .delay(101) - .duration(152) - .ease("bounce"); - }, - - "starts immediately after the previous transition ends": function(t1) { - var t2 = t1.transition(); - assert.equal(t2[0][0].__transition__[t2.id].delay, 253); - }, - "inherits the previous transition's duration": function(t1) { - var t2 = t1.transition(); - assert.equal(t2[0][0].__transition__[t2.id].duration, 152); - }, - "inherits easing": function(t1) { - // TODO how to test this? - }, - "gets a new transition id": function(t1) { - var t2 = t1.transition(); - assert.isTrue(t2.id > t1.id); - }, - - "while transitioning": { - topic: function(t1) { - var callback = this.callback; - var t2 = t1.transition().tween("custom", function() { - return function(t) { - if (callback) { - callback(null, t2); - callback = null; - } - }; - }); - }, - "increments the lock's reference count": function(t2) { - assert.isTrue(t2[0][0].__transition__.count > 1); - } - }, - - "after transitioning": { - topic: function(t1) { - var cb = this.callback; - var t2 = t1.transition(); - t2.each("end", function() { - setTimeout(function() { - cb(null, t2); - return true; - }, 50); - }); - }, - "decrements the lock's reference count": function(t2) { - assert.isFalse("__transition__" in t2[0][0]); - } - } -}; diff --git a/test/transition/transition-test-tween.js b/test/transition/transition-test-tween.js deleted file mode 100644 index f21a8a73f00b1d..00000000000000 --- a/test/transition/transition-test-tween.js +++ /dev/null @@ -1,62 +0,0 @@ -var assert = require("../assert"); - -module.exports = { - topic: function(d3) { - var cb = this.callback, - dd = [], - ii = [], - tt = [], - fails = 0; - - var s = d3.select("body").append("div").selectAll("div") - .data(["red", "green"]) - .enter().append("div") - .text(function(d) { return d3.rgb(d)+""; }); - - var t = s.transition() - .tween("text", function() { ++fails; }) - .tween("text", tween); - - function tween(d, i) { - dd.push(d); - ii.push(i); - if (tt.push(this) >= 2) cb(null, { - selection: s, - transition: t, - data: dd, - index: ii, - context: tt, - fails: fails - }); - return i && function(t) { - this.textContent = d3.hsl(230, 0.5, t) + ""; - }; - } - }, - - "defines the corresponding tween": function(result) { - assert.typeOf(result.transition.tween("text"), "function"); - }, - "the last tween takes precedence": function(result) { - assert.equal(result.fails, 0); - }, - "invokes the tween function": function(result) { - assert.deepEqual(result.data, ["red", "green"], "expected data, got {actual}"); - assert.deepEqual(result.index, [0, 1], "expected data, got {actual}"); - assert.domEqual(result.context[0], result.selection[0][0], "expected this, got {actual}"); - assert.domEqual(result.context[1], result.selection[0][1], "expected this, got {actual}"); - }, - - "end": { - topic: function(result) { - var cb = this.callback; - result.transition.each("end", function(d, i) { if (i >= 1) cb(null, result); }); - }, - "uses the returned tweener": function(result) { - assert.equal(result.selection[0][1].textContent, "#ffffff"); - }, - "does nothing if the tweener is falsey": function(result) { - assert.equal(result.selection[0][0].textContent, "#ff0000"); - } - } -}; diff --git a/test/transition/transition-test.js b/test/transition/transition-test.js deleted file mode 100644 index e4c41d2fd3cad8..00000000000000 --- a/test/transition/transition-test.js +++ /dev/null @@ -1,89 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.transition"); - -suite.addBatch({ - "transition": { - topic: load("transition/transition").document(), - "selects the document element": function(d3) { - var transition = d3.transition(); - assert.equal(transition.length, 1); - assert.equal(transition[0].length, 1); - assert.equal(transition[0][0].nodeType, 1); - assert.equal(transition[0][0].tagName, "HTML"); - }, - "is an instanceof d3.transition": function(d3) { - assert.isTrue(d3.transition() instanceof d3.transition); - }, - "subselections are also instanceof d3.transition": function(d3) { - var transition = d3.transition(); - assert.isTrue(transition.select("body") instanceof d3.transition); - assert.isTrue(transition.selectAll("body") instanceof d3.transition); - }, - "transition prototype can be extended": function(d3) { - var transition = d3.transition(), vv = []; - d3.transition.prototype.foo = function(v) { vv.push(v); return this; }; - transition.select("body").foo(42); - assert.deepEqual(vv, [42]); - delete d3.transition.prototype.foo; - } - } -}); - -// Subtransitions -suite.addBatch({ - "transition": { - topic: load("transition/transition").document(), - "select": require("./transition-test-select"), - "selectAll": require("./transition-test-selectAll"), - "transition": require("./transition-test-transition"), - "filter": require("./transition-test-filter") - } -}); - -// Content -suite.addBatch({ - "transition": { - topic: load("transition/transition").document(), - "attr": require("./transition-test-attr"), - "attrTween": require("./transition-test-attrTween"), - "style": require("./transition-test-style"), - "styleTween": require("./transition-test-styleTween"), - "text": require("./transition-test-text"), - "remove": require("./transition-test-remove") - } -}); - -// Animation -suite.addBatch({ - "transition": { - topic: load("transition/transition").document(), - "delay": require("./transition-test-delay"), - "duration": require("./transition-test-duration") - } -}); - -// Control -suite.addBatch({ - "transition": { - topic: load("transition/transition").document(), - "each": require("./transition-test-each"), - "call": require("./transition-test-call"), - "tween": require("./transition-test-tween"), - "id": require("./transition-test-id"), - "time": require("./transition-test-time") - } -}); - -// Inspection -suite.addBatch({ - "transition": { - topic: load("transition/transition").document(), - "size": require("./transition-test-size"), - "node": require("./transition-test-node") - } -}) - -suite.export(module); diff --git a/test/xhr/html-test.js b/test/xhr/html-test.js deleted file mode 100644 index aaf2f3a6dfcfd6..00000000000000 --- a/test/xhr/html-test.js +++ /dev/null @@ -1,37 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.html"); - -suite.addBatch({ - "html": { - topic: load("xhr/html").expression("d3.html").document(), - - "on a sample file": { - topic: function(html) { - html("test/data/sample.html", this.callback); - }, - "invokes the callback with the loaded html": function(document) { - assert.equal(document.getElementsByTagName("H1")[0].textContent, "Hello & world!"); - }, - "override the mime type to text/html": function(document) { - assert.equal(XMLHttpRequest._last._info.mimeType, "text/html"); - } - }, - - "on a file that does not exist": { - topic: function(html) { - var callback = this.callback; - html("//does/not/exist.html", function(error, document) { - callback(null, document); - }); - }, - "invokes the callback with undefined when an error occurs": function(document) { - assert.isUndefined(document); - } - } - } -}); - -suite.export(module); diff --git a/test/xhr/json-test.js b/test/xhr/json-test.js deleted file mode 100644 index d6ba7797eb3616..00000000000000 --- a/test/xhr/json-test.js +++ /dev/null @@ -1,51 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.json"); - -suite.addBatch({ - "json": { - topic: load("xhr/json").expression("d3.json").document(), - - "on a sample file": { - topic: function(json) { - json("test/data/sample.json", this.callback); - }, - "invokes the callback with the loaded JSON": function(json) { - assert.deepEqual(json, [{"Hello":42,"World":"\"fish\""}]); - }, - "overrides the mime type to application/json": function(json) { - assert.equal(XMLHttpRequest._last._info.mimeType, "application/json"); - } - }, - - "on a file that does not exist": { - topic: function(json) { - var callback = this.callback; - json("//does/not/exist.json", function(error, json) { - callback(null, {error: error, value: json}); - }); - }, - "invokes the callback with undefined when an error occurs": function(result) { - assert.equal(result.error.status, 404); - assert.isUndefined(result.value); - } - }, - - "on a file with invalid JSON": { - topic: function(json) { - var callback = this.callback; - json("test/data/sample.tsv", function(error, json) { - callback(null, {error: error, value: json}); - }); - }, - "invokes the callback with undefined when an error occurs": function(result) { - assert.equal(result.error.constructor.name, "SyntaxError"); - assert.isUndefined(result.value); - } - } - } -}); - -suite.export(module); diff --git a/test/xhr/text-test.js b/test/xhr/text-test.js deleted file mode 100644 index dbe123d5fdfa39..00000000000000 --- a/test/xhr/text-test.js +++ /dev/null @@ -1,46 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.text"); - -suite.addBatch({ - "text": { - topic: load("xhr/text").expression("d3.text").document(), - - "on a sample file": { - topic: function(text) { - text("test/data/sample.txt", this.callback); - }, - "invokes the callback with the loaded text": function(text) { - assert.equal(text, "Hello, world!\n"); - }, - "does not override the mime type by default": function(text) { - assert.isUndefined(XMLHttpRequest._last._info.mimeType); - } - }, - - "with a custom mime type": { - topic: function(text) { - text("test/data/sample.txt", "text/plain+sample", this.callback); - }, - "observes the optional mime type": function(text) { - assert.equal(XMLHttpRequest._last._info.mimeType, "text/plain+sample"); - } - }, - - "on a file that does not exist": { - topic: function(text) { - var callback = this.callback; - text("//does/not/exist.txt", function(error, text) { - callback(null, text); - }); - }, - "invokes the callback with undefined when an error occurs": function(text) { - assert.isUndefined(text); - } - } - } -}); - -suite.export(module); diff --git a/test/xhr/xhr-test.js b/test/xhr/xhr-test.js deleted file mode 100644 index b24722e1e534f6..00000000000000 --- a/test/xhr/xhr-test.js +++ /dev/null @@ -1,79 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.xhr"); - -suite.addBatch({ - "xhr": { - topic: load("xhr/xhr").document(), - - "on a sample text file": { - topic: function(d3) { - d3.xhr("test/data/sample.txt", this.callback); - }, - "makes an asynchronous HTTP request": function(req) { - assert.equal(req._info.url, "test/data/sample.txt"); - assert.isTrue(req._info.async); - }, - "invokes the callback with the request object": function(req) { - assert.equal(req.responseText, "Hello, world!\n"); - }, - "does not override the mime type by default": function(req) { - assert.isUndefined(req._info.mimeType); - }, - "waits until the request is done": function(req) { - assert.equal(req.readyState, 4); - assert.equal(req.status, 200); - } - }, - - "when a custom mime type is specified": { - topic: function(d3) { - d3.xhr("test/data/sample.txt", "text/plain", this.callback); - }, - "observes the optional mime type": function(req) { - assert.equal(req._info.mimeType, "text/plain"); - } - }, - - "when a beforesend listener is specified": { - topic: function(d3) { - var callback = this.callback; - var xhr = d3.xhr("test/data/sample.txt", "text/plain").on("beforesend", function(request) { - callback(null, { - that: this, - xhr: xhr, - readyState: request.readyState, - request: request - }); - }); - xhr.get(); - }, - "invokes the beforesend listener with the xhr object as the context": function(result) { - assert.equal(result.that, result.xhr); - assert.ok(result.xhr.get); - }, - "invokes the beforesend listener with the underlying XMLHttpRequest as an argument": function(result) { - assert.instanceOf(result.request, XMLHttpRequest); - }, - "invokes the beforesend listener after open and before send": function(result) { - assert.equal(result.readyState, 1); - } - }, - - "on a file that does not exist": { - topic: function(d3) { - var callback = this.callback; - d3.xhr("//does/not/exist.txt", function(error, req) { - callback(null, req); - }); - }, - "invokes the callback with undefined when an error occurs": function(req) { - assert.isUndefined(req); - } - } - } -}); - -suite.export(module); diff --git a/test/xhr/xml-test.js b/test/xhr/xml-test.js deleted file mode 100644 index 2b118f190448a8..00000000000000 --- a/test/xhr/xml-test.js +++ /dev/null @@ -1,46 +0,0 @@ -var vows = require("vows"), - load = require("../load"), - assert = require("../assert"); - -var suite = vows.describe("d3.xml"); - -suite.addBatch({ - "xml": { - topic: load("xhr/xml").expression("d3.xml").document(), - - "on a sample file": { - topic: function(xml) { - xml("test/data/sample.xml", this.callback); - }, - "invokes the callback with the loaded xml": function(xml) { - assert.deepEqual(xml, {_xml: "\n\n \n\n"}); - }, - "does not override the mime type by default": function(xml) { - assert.isUndefined(XMLHttpRequest._last._info.mimeType); - } - }, - - "with a custom mime type": { - topic: function(xml) { - xml("test/data/sample.txt", "application/xml+sample", this.callback); - }, - "observes the optional mime type": function(xml) { - assert.equal(XMLHttpRequest._last._info.mimeType, "application/xml+sample"); - } - }, - - "on a file that does not exist": { - topic: function(xml) { - var callback = this.callback; - xml("//does/not/exist.xml", function(error, xml) { - callback(null, xml); - }); - }, - "invokes the callback with undefined when an error occurs": function(xml) { - assert.isUndefined(xml); - } - } - } -}); - -suite.export(module); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000000000..5ca976b59ae9f3 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,921 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.10.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@babel/highlight@^7.12.13": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" + integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@types/node@*": + version "14.14.41" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.41.tgz#d0b939d94c1d7bd53d04824af45f1139b8c45615" + integrity sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g== + +"@types/resolve@0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + dependencies: + "@types/node" "*" + +acorn@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +builtin-modules@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" + integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +commander@2, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +d3-array@2, d3-array@>=2.5, d3-array@^2.3.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" + +d3-axis@2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-2.1.0.tgz#978db534092711117d032fad5d733d206307f6a0" + integrity sha512-z/G2TQMyuf0X3qP+Mh+2PimoJD41VOCjViJzT0BHeL/+JQAofkiWZbWxlwFGb1N8EN+Cl/CW+MUKbVzr1689Cw== + +d3-brush@2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-2.1.0.tgz#adadfbb104e8937af142e9a6e2028326f0471065" + integrity sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ== + dependencies: + d3-dispatch "1 - 2" + d3-drag "2" + d3-interpolate "1 - 2" + d3-selection "2" + d3-transition "2" + +d3-chord@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-2.0.0.tgz#32491b5665391180560f738e5c1ccd1e3c47ebae" + integrity sha512-D5PZb7EDsRNdGU4SsjQyKhja8Zgu+SHZfUSO5Ls8Wsn+jsAKUUGkcshLxMg9HDFxG3KqavGWaWkJ8EpU8ojuig== + dependencies: + d3-path "1 - 2" + +"d3-color@1 - 2", d3-color@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" + integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== + +d3-contour@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-2.0.0.tgz#80ee834988563e3bea9d99ddde72c0f8c089ea40" + integrity sha512-9unAtvIaNk06UwqBmvsdHX7CZ+NPDZnn8TtNH1myW93pWJkhsV25JcgnYAu0Ck5Veb1DHiCv++Ic5uvJ+h50JA== + dependencies: + d3-array "2" + +d3-delaunay@5: + version "5.3.0" + resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-5.3.0.tgz#b47f05c38f854a4e7b3cea80e0bb12e57398772d" + integrity sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w== + dependencies: + delaunator "4" + +"d3-dispatch@1 - 2", d3-dispatch@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-2.0.0.tgz#8a18e16f76dd3fcaef42163c97b926aa9b55e7cf" + integrity sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA== + +d3-drag@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-2.0.0.tgz#9eaf046ce9ed1c25c88661911c1d5a4d8eb7ea6d" + integrity sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w== + dependencies: + d3-dispatch "1 - 2" + d3-selection "2" + +"d3-dsv@1 - 2", d3-dsv@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-2.0.0.tgz#b37b194b6df42da513a120d913ad1be22b5fe7c5" + integrity sha512-E+Pn8UJYx9mViuIUkoc93gJGGYut6mSDKy2+XaPwccwkRGlR+LO97L2VCCRjQivTwLHkSnAJG7yo00BWY6QM+w== + dependencies: + commander "2" + iconv-lite "0.4" + rw "1" + +"d3-ease@1 - 2", d3-ease@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-2.0.0.tgz#fd1762bfca00dae4bacea504b1d628ff290ac563" + integrity sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ== + +d3-fetch@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-2.0.0.tgz#ecd7ef2128d9847a3b41b548fec80918d645c064" + integrity sha512-TkYv/hjXgCryBeNKiclrwqZH7Nb+GaOwo3Neg24ZVWA3MKB+Rd+BY84Nh6tmNEMcjUik1CSUWjXYndmeO6F7sw== + dependencies: + d3-dsv "1 - 2" + +d3-force@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-2.1.1.tgz#f20ccbf1e6c9e80add1926f09b51f686a8bc0937" + integrity sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew== + dependencies: + d3-dispatch "1 - 2" + d3-quadtree "1 - 2" + d3-timer "1 - 2" + +"d3-format@1 - 2", d3-format@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" + integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== + +d3-geo@2: + version "2.0.1" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-2.0.1.tgz#2437fdfed3fe3aba2812bd8f30609cac83a7ee39" + integrity sha512-M6yzGbFRfxzNrVhxDJXzJqSLQ90q1cCyb3EWFZ1LF4eWOBYxFypw7I/NFVBNXKNqxv1bqLathhYvdJ6DC+th3A== + dependencies: + d3-array ">=2.5" + +d3-hierarchy@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz#dab88a58ca3e7a1bc6cab390e89667fcc6d20218" + integrity sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw== + +"d3-interpolate@1 - 2", "d3-interpolate@1.2.0 - 2", d3-interpolate@2: + version "2.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" + integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== + dependencies: + d3-color "1 - 2" + +"d3-path@1 - 2", d3-path@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" + integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== + +d3-polygon@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-2.0.0.tgz#13608ef042fbec625ba1598327564f03c0396d8e" + integrity sha512-MsexrCK38cTGermELs0cO1d79DcTsQRN7IWMJKczD/2kBjzNXxLUWP33qRF6VDpiLV/4EI4r6Gs0DAWQkE8pSQ== + +"d3-quadtree@1 - 2", d3-quadtree@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-2.0.0.tgz#edbad045cef88701f6fee3aee8e93fb332d30f9d" + integrity sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw== + +d3-random@2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-2.2.2.tgz#5eebd209ef4e45a2b362b019c1fb21c2c98cbb6e" + integrity sha512-0D9P8TRj6qDAtHhRQn6EfdOtHMfsUWanl3yb/84C4DqpZ+VsgfI5iTVRNRbELCfNvRfpMr8OrqqUTQ6ANGCijw== + +d3-scale-chromatic@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz#c13f3af86685ff91323dc2f0ebd2dabbd72d8bab" + integrity sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA== + dependencies: + d3-color "1 - 2" + d3-interpolate "1 - 2" + +d3-scale@3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" + integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== + dependencies: + d3-array "^2.3.0" + d3-format "1 - 2" + d3-interpolate "1.2.0 - 2" + d3-time "^2.1.1" + d3-time-format "2 - 3" + +d3-selection@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-2.0.0.tgz#94a11638ea2141b7565f883780dabc7ef6a61066" + integrity sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA== + +d3-shape@2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" + integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== + dependencies: + d3-path "1 - 2" + +"d3-time-format@2 - 3", d3-time-format@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" + integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== + dependencies: + d3-time "1 - 2" + +"d3-time@1 - 2", d3-time@2, d3-time@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" + integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== + dependencies: + d3-array "2" + +"d3-timer@1 - 2", d3-timer@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-2.0.0.tgz#055edb1d170cfe31ab2da8968deee940b56623e6" + integrity sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA== + +d3-transition@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-2.0.0.tgz#366ef70c22ef88d1e34105f507516991a291c94c" + integrity sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog== + dependencies: + d3-color "1 - 2" + d3-dispatch "1 - 2" + d3-ease "1 - 2" + d3-interpolate "1 - 2" + d3-timer "1 - 2" + +d3-zoom@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-2.0.0.tgz#f04d0afd05518becce879d04709c47ecd93fba54" + integrity sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw== + dependencies: + d3-dispatch "1 - 2" + d3-drag "2" + d3-interpolate "1 - 2" + d3-selection "2" + d3-transition "2" + +deep-equal@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +delaunator@4: + version "4.0.1" + resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-4.0.1.tgz#3d779687f57919a7a418f8ab947d3bddb6846957" + integrity sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag== + +dotignore@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" + integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== + dependencies: + minimatch "^3.0.4" + +es-abstract@^1.18.0-next.2: + version "1.18.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" + integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.2" + is-string "^1.0.5" + object-inspect "^1.9.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +estree-walker@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + integrity sha1-va/oCVOD2EFNXcLs9MkXO225QS4= + +estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + +for-each@~0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1, function-bind@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +glob@^7.1.3, glob@~7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has@^1.0.3, has@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +iconv-lite@0.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + +is-arguments@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" + +is-bigint@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" + integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== + +is-boolean-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" + integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + dependencies: + call-bind "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + +is-core-module@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-number-object@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" + integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== + +is-regex@^1.0.4, is-regex@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" + integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.1" + +is-regex@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +jsesc@^2.2.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json2module@0.0: + version "0.0.3" + resolved "https://registry.yarnpkg.com/json2module/-/json2module-0.0.3.tgz#00fb5f4a9b7adfc3f0647c29cb17bcd1979be9b2" + integrity sha1-APtfSpt638PwZHwpyxe80Zeb6bI= + dependencies: + rw "^1.3.2" + +magic-string@^0.15.1: + version "0.15.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.15.2.tgz#0681d7388741bbc3addaa65060992624c6c09e9c" + integrity sha1-BoHXOIdBu8Ot2qZQYJkmJMbAnpw= + dependencies: + vlq "^0.2.1" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@~1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +object-inspect@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== + +object-inspect@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +resolve@^1.11.1: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +resolve@~1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= + dependencies: + through "~2.3.4" + +rimraf@3: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup-plugin-ascii@0.0: + version "0.0.3" + resolved "https://registry.yarnpkg.com/rollup-plugin-ascii/-/rollup-plugin-ascii-0.0.3.tgz#2057a6d65c00573d1ca5b2649ce4e531b042cde7" + integrity sha1-IFem1lwAVz0cpbJknOTlMbBCzec= + dependencies: + acorn "^3.2.0" + estree-walker "^0.2.1" + jsesc "^2.2.0" + magic-string "^0.15.1" + rollup-pluginutils "^1.5.0" + +rollup-plugin-node-resolve@5: + version "5.2.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz#730f93d10ed202473b1fb54a5997a7db8c6d8523" + integrity sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw== + dependencies: + "@types/resolve" "0.0.8" + builtin-modules "^3.1.0" + is-module "^1.0.0" + resolve "^1.11.1" + rollup-pluginutils "^2.8.1" + +rollup-plugin-terser@7: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup-pluginutils@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + integrity sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg= + dependencies: + estree-walker "^0.2.1" + minimatch "^3.0.2" + +rollup-pluginutils@^2.8.1: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + +rollup@2: + version "2.45.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.45.2.tgz#8fb85917c9f35605720e92328f3ccbfba6f78b48" + integrity sha512-kRRU7wXzFHUzBIv0GfoFFIN3m9oteY4uAsKllIpQDId5cfnkWF2J130l+27dzDju0E6MScKiV0ZM5Bw8m4blYQ== + optionalDependencies: + fsevents "~2.3.1" + +rw@1, rw@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" + integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +source-map-support@~0.5.19: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +string.prototype.trim@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.4.tgz#6014689baf5efaf106ad031a5fa45157666ed1bd" + integrity sha512-hWCk/iqf7lp0/AgTF7/ddO1IWtSNPASjlzCicV5irAVdE1grjsneK26YG6xACMBEdCvO8fUST0UzDMh/2Qy+9Q== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +tape-await@0.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/tape-await/-/tape-await-0.1.2.tgz#41f99110a2bc4728732d8bc058278b2fbf3c0bec" + integrity sha512-Gt1bXilp9uRTVj+DecLDs37tP1XwGXfFzWVqQEfW7foO9TNacy+aN5TdT0Kv6LI5t/9l3iOE4nX2hr2SQ4+OSg== + +tape@4: + version "4.13.3" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.13.3.tgz#51b3d91c83668c7a45b1a594b607dee0a0b46278" + integrity sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw== + dependencies: + deep-equal "~1.1.1" + defined "~1.0.0" + dotignore "~0.1.2" + for-each "~0.3.3" + function-bind "~1.1.1" + glob "~7.1.6" + has "~1.0.3" + inherits "~2.0.4" + is-regex "~1.0.5" + minimist "~1.2.5" + object-inspect "~1.7.0" + resolve "~1.17.0" + resumer "~0.0.0" + string.prototype.trim "~1.2.1" + through "~2.3.8" + +terser@^5.0.0: + version "5.6.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.6.1.tgz#a48eeac5300c0a09b36854bf90d9c26fb201973c" + integrity sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.19" + +through@~2.3.4, through@~2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +unbox-primitive@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +vlq@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" + integrity sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow== + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=