├── .gitignore ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── config.rb ├── csv ├── us-state.csv └── world.csv ├── mapper.png └── source ├── data ├── src │ ├── us-state1.json │ ├── us-state2.json │ ├── world-110m-meta.json │ ├── world-110m.json │ ├── world-50m.json │ └── world │ │ ├── countries.js │ │ ├── parser.js │ │ └── world.js ├── us-county.json ├── us-state.json └── world.json ├── images ├── background.png ├── share-embed.png ├── share-png.png ├── share-svg.png └── texture.png ├── index.html.erb ├── javascripts ├── application.js ├── mapper │ ├── interactive.js │ ├── main.js │ ├── models │ │ ├── data.js │ │ ├── settings.js │ │ └── styles.js │ ├── render.js │ └── views │ │ ├── editor-data.js │ │ ├── editor-main.js │ │ ├── editor-settings.js │ │ ├── editor-style-base.js │ │ ├── editor-style-list.js │ │ └── map-preview.js ├── renderer.js └── vendor │ ├── backbone.epoxy.js │ ├── backbone.js │ ├── canvg │ ├── MIT-LICENSE.txt │ ├── StackBlur.js │ ├── canvg.js │ └── rgbcolor.js │ ├── d3.geo.projection.v0.min.js │ ├── d3.times.projection.js │ ├── d3.v3.min.js │ ├── jquery.js │ ├── topojson.v1.min.js │ └── underscore.js ├── layouts └── layout.erb ├── partials ├── _m-editor-data.html.erb ├── _m-editor-settings.html.erb ├── _m-editor-style-base.html.erb ├── _m-editor-style-fill.html.erb ├── _m-editor-style-stroke.html.erb ├── _m-editor-style.html.erb └── _m-map-preview.html.erb ├── renderer.html.erb └── stylesheets ├── _base.scss ├── _layout.scss ├── _mixins.scss ├── _typography.scss ├── _vars.scss ├── application.scss ├── modules ├── _m-editor-data.scss ├── _m-editor-settings.scss ├── _m-editor-style.scss ├── _m-editor.scss ├── _m-map-preview.scss └── _m-share.scss └── tooltip.css /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile ~/.gitignore_global 6 | 7 | # Ignore bundler config 8 | /.bundle 9 | /.ruby-version 10 | /build 11 | 12 | # Ignore cache 13 | /.sass-cache 14 | /.cache 15 | 16 | # Ignore .DS_store file 17 | .DS_Store -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # If you have OpenSSL installed, we recommend updating 2 | # the following line to use "https" 3 | source 'http://rubygems.org' 4 | 5 | gem "middleman", "~>3.3.6" 6 | 7 | # Live-reloading plugin 8 | gem "middleman-livereload", "~> 3.1.0" 9 | 10 | # For faster file watcher updates on Windows: 11 | gem "wdm", "~> 0.1.0", :platforms => [:mswin, :mingw] 12 | 13 | # Windows does not come with time zone data 14 | gem "tzinfo-data", platforms: [:mswin, :mingw] 15 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (4.1.7) 5 | i18n (~> 0.6, >= 0.6.9) 6 | json (~> 1.7, >= 1.7.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.1) 9 | tzinfo (~> 1.1) 10 | celluloid (0.16.0) 11 | timers (~> 4.0.0) 12 | chunky_png (1.3.3) 13 | coffee-script (2.3.0) 14 | coffee-script-source 15 | execjs 16 | coffee-script-source (1.8.0) 17 | compass (1.0.1) 18 | chunky_png (~> 1.2) 19 | compass-core (~> 1.0.1) 20 | compass-import-once (~> 1.0.5) 21 | rb-fsevent (>= 0.9.3) 22 | rb-inotify (>= 0.9) 23 | sass (>= 3.3.13, < 3.5) 24 | compass-core (1.0.1) 25 | multi_json (~> 1.0) 26 | sass (>= 3.3.0, < 3.5) 27 | compass-import-once (1.0.5) 28 | sass (>= 3.2, < 3.5) 29 | em-websocket (0.5.1) 30 | eventmachine (>= 0.12.9) 31 | http_parser.rb (~> 0.6.0) 32 | erubis (2.7.0) 33 | eventmachine (1.0.3) 34 | execjs (2.2.2) 35 | ffi (1.9.6) 36 | haml (4.0.5) 37 | tilt 38 | hike (1.2.3) 39 | hitimes (1.2.2) 40 | hooks (0.4.0) 41 | uber (~> 0.0.4) 42 | http_parser.rb (0.6.0) 43 | i18n (0.6.11) 44 | json (1.8.1) 45 | kramdown (1.5.0) 46 | listen (2.7.11) 47 | celluloid (>= 0.15.2) 48 | rb-fsevent (>= 0.9.3) 49 | rb-inotify (>= 0.9) 50 | middleman (3.3.7) 51 | coffee-script (~> 2.2) 52 | compass (>= 1.0.0, < 2.0.0) 53 | compass-import-once (= 1.0.5) 54 | execjs (~> 2.0) 55 | haml (>= 4.0.5) 56 | kramdown (~> 1.2) 57 | middleman-core (= 3.3.7) 58 | middleman-sprockets (>= 3.1.2) 59 | sass (>= 3.4.0, < 4.0) 60 | uglifier (~> 2.5) 61 | middleman-core (3.3.7) 62 | activesupport (~> 4.1.0) 63 | bundler (~> 1.1) 64 | erubis 65 | hooks (~> 0.3) 66 | i18n (~> 0.6.9) 67 | listen (>= 2.7.9, < 3.0) 68 | padrino-helpers (~> 0.12.3) 69 | rack (>= 1.4.5, < 2.0) 70 | rack-test (~> 0.6.2) 71 | thor (>= 0.15.2, < 2.0) 72 | tilt (~> 1.4.1, < 2.0) 73 | middleman-livereload (3.1.1) 74 | em-websocket (>= 0.2.0) 75 | middleman-core (>= 3.0.2) 76 | multi_json (~> 1.0) 77 | rack-livereload 78 | middleman-sprockets (3.3.10) 79 | middleman-core (~> 3.3) 80 | sprockets (~> 2.12.1) 81 | sprockets-helpers (~> 1.1.0) 82 | sprockets-sass (~> 1.2.0) 83 | minitest (5.4.2) 84 | multi_json (1.10.1) 85 | padrino-helpers (0.12.4) 86 | i18n (~> 0.6, >= 0.6.7) 87 | padrino-support (= 0.12.4) 88 | tilt (~> 1.4.1) 89 | padrino-support (0.12.4) 90 | activesupport (>= 3.1) 91 | rack (1.5.2) 92 | rack-livereload (0.3.15) 93 | rack 94 | rack-test (0.6.2) 95 | rack (>= 1.0) 96 | rb-fsevent (0.9.4) 97 | rb-inotify (0.9.5) 98 | ffi (>= 0.5.0) 99 | sass (3.4.7) 100 | sprockets (2.12.3) 101 | hike (~> 1.2) 102 | multi_json (~> 1.0) 103 | rack (~> 1.0) 104 | tilt (~> 1.1, != 1.3.0) 105 | sprockets-helpers (1.1.0) 106 | sprockets (~> 2.0) 107 | sprockets-sass (1.2.0) 108 | sprockets (~> 2.0) 109 | tilt (~> 1.1) 110 | thor (0.19.1) 111 | thread_safe (0.3.4) 112 | tilt (1.4.1) 113 | timers (4.0.1) 114 | hitimes 115 | tzinfo (1.2.2) 116 | thread_safe (~> 0.1) 117 | uber (0.0.11) 118 | uglifier (2.5.3) 119 | execjs (>= 0.3.0) 120 | json (>= 1.8.0) 121 | 122 | PLATFORMS 123 | ruby 124 | 125 | DEPENDENCIES 126 | middleman (~> 3.3.6) 127 | middleman-livereload (~> 3.1.0) 128 | tzinfo-data 129 | wdm (~> 0.1.0) 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Vox Media, Inc. All rights reserved. 2 | 3 | BSD license 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 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. 10 | 11 | Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | 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 HOLDER 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. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mapper 2 | 3 | This tool uses D3 to generate choropleth map graphics based upon a data set. Drop in your CSV data, configure your color thresholds, and adjust your display settings. This is a proof of concept app that still needs many features built out, however we welcome any editorial community to use this as a starting point for building great mapping tools. Existing features: 4 | 5 | - World and US State maps. 6 | - Thresholds and heat scale fill rendering. 7 | - Stroke rendering for select shapes. 8 | - Basic legend layout. 9 | - Export as PNG 10 | - Export as SVG (needs cleanup) 11 | - Interactive tooltip (needs interactive export option) 12 | 13 | ![Mapper](mapper.png) 14 | 15 | ## Getting Started 16 | 17 | **1) Install Middleman and the app:** 18 | 19 | ``` 20 | gem install middleman 21 | cd mapper 22 | bundle install 23 | ``` 24 | 25 | **2) To run the app:** 26 | 27 | ``` 28 | bundle exec middleman 29 | ``` 30 | 31 | The app should startup at `localhost:4567`. 32 | 33 | **3) To build the app:** 34 | 35 | ``` 36 | bundle exec middleman build 37 | ``` 38 | 39 | This will generate a static `/build` directory with flat HTML, CSS, and JS files that may be uploaded to any web server. 40 | 41 | ## Documentation 42 | 43 | Use the provided CSV templates to format your data: 44 | 45 | - `csv/us-state.csv` 46 | - `csv/world.csv` 47 | 48 | You may add additional columns to those data templates. The mapper application only requires that the `id` column remain unchanged for mapping shapes to data rows. 49 | 50 | ## Contribute 51 | 52 | This is a proof of concept project and we encourage contributions. [Please review our guidelines and code of conduct before contributing](https://github.com/voxmedia/open-source-contribution-guidelines). 53 | 54 | ## Author(s) 55 | 56 | - Greg MacWilliam, Vox Media. 57 | -------------------------------------------------------------------------------- /config.rb: -------------------------------------------------------------------------------- 1 | ### 2 | # Compass 3 | ### 4 | 5 | # Change Compass configuration 6 | # compass_config do |config| 7 | # config.output_style = :compact 8 | # end 9 | 10 | ### 11 | # Page options, layouts, aliases and proxies 12 | ### 13 | 14 | # Per-page layout changes: 15 | # 16 | # With no layout 17 | # page "/path/to/file.html", :layout => false 18 | # 19 | # With alternative layout 20 | # page "/path/to/file.html", :layout => :otherlayout 21 | # 22 | # A path which all have the same layout 23 | # with_layout :admin do 24 | # page "/admin/*" 25 | # end 26 | 27 | # Proxy pages (http://middlemanapp.com/basics/dynamic-pages/) 28 | # proxy "/this-page-has-no-template.html", "/template-file.html", :locals => { 29 | # :which_fake_page => "Rendering a fake page with a local variable" } 30 | 31 | ### 32 | # Helpers 33 | ### 34 | 35 | # Automatic image dimensions on image_tag helper 36 | # activate :automatic_image_sizes 37 | 38 | # Reload the browser automatically whenever files change 39 | # configure :development do 40 | # activate :livereload 41 | # end 42 | 43 | # Methods defined in the helpers block are available in templates 44 | # helpers do 45 | # def some_helper 46 | # "Helping" 47 | # end 48 | # end 49 | 50 | set :css_dir, 'stylesheets' 51 | set :js_dir, 'javascripts' 52 | set :images_dir, 'images' 53 | set :fonts_dir, 'fonts' 54 | 55 | # Build-specific configuration 56 | configure :build do 57 | # For example, change the Compass output style for deployment 58 | # activate :minify_css 59 | 60 | # Minify Javascript on build 61 | # activate :minify_javascript 62 | 63 | # Enable cache buster 64 | # activate :asset_hash 65 | 66 | # Use relative URLs 67 | activate :relative_assets 68 | 69 | # Or use a different image path 70 | # set :http_prefix, "/Content/images/" 71 | end 72 | -------------------------------------------------------------------------------- /csv/us-state.csv: -------------------------------------------------------------------------------- 1 | id,postal,name,value 2 | 2,ak,Alaska,0 3 | 1,al,Alabama,0 4 | 5,ar,Arkansas,0 5 | 4,az,Arizona,0 6 | 6,ca,California,0 7 | 8,co,Colorado,0 8 | 9,ct,Connecticut,0 9 | 11,dc,District of Columbia,0 10 | 10,de,Deleware,0 11 | 12,fl,Florida,0 12 | 13,ga,Georgia,0 13 | 15,hi,Hawaii,0 14 | 19,ia,Iowa,0 15 | 16,id,Idaho,0 16 | 17,il,Illinois,0 17 | 18,in,Indiana,0 18 | 20,ks,Kansas,0 19 | 21,ky,Kentucky,0 20 | 22,la,Louisiana,0 21 | 25,ma,Massachusetts,0 22 | 24,md,Maryland,0 23 | 23,me,Maine,0 24 | 27,mn,Minnesota,0 25 | 29,mo,Missouri,0 26 | 28,ms,Mississippi,0 27 | 30,mt,Montana,0 28 | 37,nc,North Carolina,0 29 | 38,nd,North Dakota,0 30 | 31,ne,Nebraska,0 31 | 33,nh,New Hampshire,0 32 | 34,nj,New Jersey,0 33 | 35,nm,New Mexico,0 34 | 32,nv,Nevada,0 35 | 36,ny,New York,0 36 | 39,oh,Ohio,0 37 | 40,ok,Oklahoma,0 38 | 41,or,Oregon,0 39 | 42,pa,Pennsylvania,0 40 | 44,ri,Rhode Island,0 41 | 45,sc,South Carolina,0 42 | 46,sd,South Dakota,0 43 | 47,tn,Tennessee,0 44 | 48,tx,Texas,0 45 | 49,ut,Utah,0 46 | 51,va,Virginia,0 47 | 50,vt,Vermont,0 48 | 53,wa,Washington,0 49 | 55,wi,Wisconsin,0 50 | 54,wv,West Virginia,0 51 | 56,wy,Wyoming,0 -------------------------------------------------------------------------------- /csv/world.csv: -------------------------------------------------------------------------------- 1 | id,name,value 2 | 004,Afghanistan,0 3 | 008,Albania,0 4 | 012,Algeria,0 5 | 024,Angola,0 6 | 031,Azerbaijan,0 7 | 032,Argentina,0 8 | 036,Australia,0 9 | 040,Austria,0 10 | 044,Bahamas,0 11 | 050,Bangladesh,0 12 | 051,Armenia,0 13 | 056,Belgium,0 14 | 064,Bhutan,0 15 | 068,Bolivia,0 16 | 070,Bosnia and Herzegovina,0 17 | 072,Botswana,0 18 | 076,Brazil,0 19 | 084,Belize,0 20 | 090,Solomon Islands,0 21 | 096,Brunei Darussalam,0 22 | 100,Bulgaria,0 23 | 104,Myanmar,0 24 | 108,Burundi,0 25 | 112,Belarus,0 26 | 116,Cambodia,0 27 | 120,Cameroon,0 28 | 124,Canada,0 29 | 140,Central African Republic,0 30 | 144,Sri Lanka,0 31 | 148,Chad,0 32 | 152,Chile,0 33 | 156,China,0 34 | 158,Taiwan,0 35 | 170,Colombia,0 36 | 178,Congo,0 37 | 180,Democratic Republic of the Congo,0 38 | 188,Costa Rica,0 39 | 191,Croatia,0 40 | 192,Cuba,0 41 | 196,Cyprus,0 42 | 203,Czech Republic,0 43 | 204,Benin,0 44 | 208,Denmark,0 45 | 214,Dominican Republic,0 46 | 218,Ecuador,0 47 | 222,El Salvador,0 48 | 226,Equatorial Guinea,0 49 | 231,Ethiopia,0 50 | 232,Eritrea,0 51 | 233,Estonia,0 52 | 238,Falkland Islands,0 53 | 242,Fiji,0 54 | 246,Finland,0 55 | 250,France,0 56 | 260,French Southern Territories,0 57 | 262,Djibouti,0 58 | 266,Gabon,0 59 | 268,Georgia,0 60 | 270,Gambia,0 61 | 275,Palestine,0 62 | 276,Germany,0 63 | 288,Ghana,0 64 | 300,Greece,0 65 | 304,Greenland,0 66 | 320,Guatemala,0 67 | 324,Guinea,0 68 | 328,Guyana,0 69 | 332,Haiti,0 70 | 340,Honduras,0 71 | 348,Hungary,0 72 | 352,Iceland,0 73 | 356,India,0 74 | 360,Indonesia,0 75 | 364,Iran,0 76 | 368,Iraq,0 77 | 372,Ireland,0 78 | 376,Israel,0 79 | 380,Italy,0 80 | 384,Côte d'Ivoire,0 81 | 388,Jamaica,0 82 | 392,Japan,0 83 | 398,Kazakhstan,0 84 | 400,Jordan,0 85 | 404,Kenya,0 86 | 408,North Korea,0 87 | 410,South Korea,0 88 | 414,Kuwait,0 89 | 417,Kyrgyzstan,0 90 | 418,Laos,0 91 | 422,Lebanon,0 92 | 426,Lesotho,0 93 | 428,Latvia,0 94 | 430,Liberia,0 95 | 434,Libya,0 96 | 440,Lithuania,0 97 | 442,Luxembourg,0 98 | 450,Madagascar,0 99 | 454,Malawi,0 100 | 458,Malaysia,0 101 | 466,Mali,0 102 | 478,Mauritania,0 103 | 484,Mexico,0 104 | 496,Mongolia,0 105 | 498,Moldova,0 106 | 499,Montenegro,0 107 | 504,Morocco,0 108 | 508,Mozambique,0 109 | 512,Oman,0 110 | 516,Namibia,0 111 | 524,Nepal,0 112 | 528,Netherlands,0 113 | 540,New Caledonia,0 114 | 548,Vanuatu,0 115 | 554,New Zealand,0 116 | 558,Nicaragua,0 117 | 562,Niger,0 118 | 566,Nigeria,0 119 | 578,Norway,0 120 | 586,Pakistan,0 121 | 591,Panama,0 122 | 598,Papua New Guinea,0 123 | 600,Paraguay,0 124 | 604,Peru,0 125 | 608,Philippines,0 126 | 616,Poland,0 127 | 620,Portugal,0 128 | 624,Guinea-Bissau,0 129 | 626,Timor-Leste,0 130 | 630,Puerto Rico,0 131 | 634,Qatar,0 132 | 642,Romania,0 133 | 643,Russian Federation,0 134 | 646,Rwanda,0 135 | 682,Saudi Arabia,0 136 | 686,Senegal,0 137 | 688,Serbia,0 138 | 694,Sierra Leone,0 139 | 703,Slovakia,0 140 | 704,Viet Nam,0 141 | 705,Slovenia,0 142 | 706,Somalia,0 143 | 710,South Africa,0 144 | 716,Zimbabwe,0 145 | 724,Spain,0 146 | 728,South Sudan,0 147 | 729,Sudan,0 148 | 732,Western Sahara,0 149 | 740,Suriname,0 150 | 748,Swaziland,0 151 | 752,Sweden,0 152 | 756,Switzerland,0 153 | 760,Syrian Arab Republic,0 154 | 762,Tajikistan,0 155 | 764,Thailand,0 156 | 768,Togo,0 157 | 780,Trinidad and Tobago,0 158 | 784,United Arab Emirates,0 159 | 788,Tunisia,0 160 | 792,Turkey,0 161 | 795,Turkmenistan,0 162 | 800,Uganda,0 163 | 804,Ukraine,0 164 | 807,Macedonia,0 165 | 818,Egypt,0 166 | 826,United Kingdom,0 167 | 834,Tanzania,0 168 | 840,United States,0 169 | 854,Burkina Faso,0 170 | 858,Uruguay,0 171 | 860,Uzbekistan,0 172 | 862,Venezuela,0 173 | 887,Yemen,0 174 | 894,Zambia,0 -------------------------------------------------------------------------------- /mapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/mapper/b9bb8c751d8e07422eb564fcace8cbd83150f7b6/mapper.png -------------------------------------------------------------------------------- /source/data/src/us-state2.json: -------------------------------------------------------------------------------- 1 | {"type":"Topology","objects":{"states":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":"Maryland","arcs":[[0,1,2,3,4,5,6,7,8,9]]},{"type":"Polygon","id":"Minnesota","arcs":[[10,11,12,13,14]]},{"type":"Polygon","id":"Montana","arcs":[[15,16,17,18,19]]},{"type":"Polygon","id":"North Dakota","arcs":[[20,-18,21,-13]]},{"type":"MultiPolygon","id":"Hawaii","arcs":[[[22]],[[23]],[[24]],[[25]],[[26]]]},{"type":"Polygon","id":"Idaho","arcs":[[27,28,29,30,31,32,-16,33]]},{"type":"Polygon","id":"Washington","arcs":[[34,35,-32]]},{"type":"Polygon","id":"Arizona","arcs":[[36,37,38,39,40]]},{"type":"Polygon","id":"California","arcs":[[-37,41,42,43]]},{"type":"Polygon","id":"Colorado","arcs":[[44,45,46,47,48,49]]},{"type":"Polygon","id":"Nevada","arcs":[[-44,50,-29,51,-38]]},{"type":"Polygon","id":"New Mexico","arcs":[[52,-46,53,54,55]]},{"type":"Polygon","id":"Oregon","arcs":[[-51,-43,56,-35,-31,57]]},{"type":"Polygon","id":"Wyoming","arcs":[[58,-34,-20,59,60,-48]]},{"type":"Polygon","id":"Arkansas","arcs":[[61,62,63,64,65,66]]},{"type":"Polygon","id":"Iowa","arcs":[[67,68,69,70,-11,71]]},{"type":"Polygon","id":"Kansas","arcs":[[72,-50,73,74,75,76]]},{"type":"Polygon","id":"Missouri","arcs":[[77,78,-66,79,80,81,-75,82,-69,83]]},{"type":"Polygon","id":"Nebraska","arcs":[[-83,-74,-49,-61,84,-70]]},{"type":"Polygon","id":"Oklahoma","arcs":[[85,-54,-45,-73,86,-80,-65]]},{"type":"Polygon","id":"South Dakota","arcs":[[-85,-60,-19,-21,-12,-71]]},{"type":"Polygon","id":"Louisiana","arcs":[[87,88,89,90,-63]]},{"type":"Polygon","id":"Texas","arcs":[[-91,91,-55,-86,-64]]},{"type":"Polygon","id":"Connecticut","arcs":[[92,93,94,95]]},{"type":"Polygon","id":"Massachusetts","arcs":[[96,-94,97,98,99,100]]},{"type":"Polygon","id":"New Hampshire","arcs":[[101,102,103,104,-100]]},{"type":"Polygon","id":"Rhode Island","arcs":[[-97,105,-95]]},{"type":"Polygon","id":"Vermont","arcs":[[-99,106,107,-102]]},{"type":"Polygon","id":"Alabama","arcs":[[108,109,110,111,112]]},{"type":"Polygon","id":"Florida","arcs":[[-109,113,114]]},{"type":"Polygon","id":"Georgia","arcs":[[-114,-113,115,116,117,118]]},{"type":"Polygon","id":"Mississippi","arcs":[[-62,119,-111,120,121]]},{"type":"Polygon","id":"South Carolina","arcs":[[-118,122,123]]},{"type":"Polygon","id":"Illinois","arcs":[[124,125,-84,-68,126,127]]},{"type":"Polygon","id":"Indiana","arcs":[[128,129,-125,130,131]]},{"type":"Polygon","id":"Kentucky","arcs":[[132,133,134,-78,-126,-130,135]]},{"type":"Polygon","id":"North Carolina","arcs":[[-123,-117,136,137,138]]},{"type":"Polygon","id":"Ohio","arcs":[[-136,-129,139,140,141,142]]},{"type":"Polygon","id":"Tennessee","arcs":[[143,-137,-116,-112,-120,-67,-79,-135]]},{"type":"Polygon","id":"Wisconsin","arcs":[[-127,-72,-15,144,145,146]]},{"type":"Polygon","id":"West Virginia","arcs":[[147,-8,148,-133,-143,149]]},{"type":"Polygon","id":"Delaware","arcs":[[-1,150,151,152]]},{"type":"Polygon","id":"New Jersey","arcs":[[-152,153,154,155]]},{"type":"Polygon","id":"New York","arcs":[[-98,-93,156,-155,157,158,-107]]},{"type":"Polygon","id":"Pennsylvania","arcs":[[-151,-10,-150,-142,159,-158,-154]]},{"type":"Polygon","id":"Maine","arcs":[[-104,160]]},{"type":"MultiPolygon","id":"Michigan","arcs":[[[-140,-132,161]],[[162,163]]]},{"type":"MultiPolygon","id":"Alaska","arcs":[[[164]],[[165]],[[166]],[[167]]]},{"type":"MultiPolygon","id":"Virginia","arcs":[[[-7,168,-5,169,-138,-144,-134,-149]],[[2,170]]]},{"type":"Polygon","id":"District of Columbia","arcs":[[-6,-169]]},{"type":"Polygon","id":"Utah","arcs":[[-52,-28,-59,171,-39]]}]}},"arcs":[[[9157,3967],[7,-243],[63,0]],[[9227,3724],[0,-9],[-31,-74]],[[9196,3641],[-22,-3],[-11,-12]],[[9163,3626],[-15,22],[-12,19],[-10,15],[-12,17],[-2,29],[-2,31],[-2,28],[-2,35],[-3,35],[-7,-32],[-5,-25],[-6,-25],[5,-31],[5,-32],[5,-28],[5,-30],[-12,6],[-13,6],[-17,8],[-21,10]],[[9042,3684],[-1,6],[-4,21],[-16,-9],[-12,11],[10,42],[13,14],[4,4],[1,16]],[[9037,3789],[3,3],[2,3],[3,4],[2,3],[3,4],[-3,4],[-2,4],[-3,4],[-2,4],[-2,3],[-3,-2],[-2,-3],[-3,-4]],[[9030,3816],[-18,22],[-20,11],[1,5],[6,16],[-13,14],[-11,5],[-3,1]],[[8972,3890],[-7,25],[-12,27],[-29,15],[-19,-14],[-10,-15],[-28,8],[-13,-20],[-19,-7],[-16,-22]],[[8819,3887],[-15,-17],[1,96]],[[8805,3966],[88,0],[31,0],[67,1],[82,-1],[84,1]],[[7684,4687],[-125,4],[-139,-2],[-130,-2],[-104,0]],[[7186,4687],[1,178],[-12,183],[-16,15],[-10,29],[5,26],[22,21],[1,28]],[[7177,5167],[1,35],[-6,29],[-8,30],[-5,39],[-1,44],[-3,10],[-4,56],[-1,26],[-2,22],[-4,39],[-12,39],[-11,35],[-2,35],[-1,37],[3,24],[1,23],[-9,27],[-1,19]],[[7112,5736],[197,0],[0,73],[33,1],[17,-105],[29,-32],[67,-12],[97,-30],[93,-59],[77,25],[117,-50],[-97,-63],[-68,-76],[-64,-81],[-1,-28]],[[7609,5299],[-25,-10],[1,-107],[-3,0],[-23,-21],[-21,-18],[-13,-36],[20,-35],[-8,-48],[0,-52],[-3,-42],[28,-36],[12,-2],[31,-27],[10,-13],[7,-21],[24,-32],[32,-29],[3,-15],[1,-46],[2,-22]],[[5790,4879],[-10,10],[-10,27],[-10,5],[-14,-38],[-21,-6],[-54,12],[-3,-19],[-31,7],[-18,-26],[-17,49],[-11,28],[-20,5],[-6,14],[-6,50],[-17,23],[-10,61],[-12,26],[-11,5],[-10,-27],[-19,-22],[-17,18],[-1,49],[11,13],[-8,49],[9,50],[11,42],[-29,2],[-24,27],[-27,59],[-16,30],[-22,18],[-18,30],[0,35],[-25,50],[-7,201]],[[5317,5736],[285,0],[285,0],[285,0],[285,1]],[[6457,5737],[1,-350],[5,-232]],[[6463,5155],[-5,-174]],[[6458,4981],[-159,2],[-171,-1],[-149,2],[-188,-2],[1,-97],[-2,-6]],[[7177,5167],[-181,-10],[-155,0],[-196,-1],[-182,-1]],[[6457,5737],[330,-1],[325,0]],[[1549,31],[-14,-31],[-23,27],[3,53],[-16,70],[4,21],[17,31],[-7,37],[6,18],[7,-3],[37,-33],[17,-16],[15,-26],[25,-67],[-3,-10],[-37,-41],[-31,-30]],[[1498,329],[-32,-14],[-16,40],[-11,16],[-1,12],[9,16],[34,-18],[25,-29],[-8,-23]],[[1433,431],[-3,-21],[-51,5],[7,24],[47,-8]],[[1348,458],[-5,-11],[-7,3],[-33,6],[-12,44],[-4,7],[26,27],[8,-13],[27,-63]],[[1187,584],[-12,-19],[-32,35],[5,14],[15,19],[22,-5],[2,-44]],[[5793,4401],[-284,-1]],[[5509,4400],[-286,1]],[[5223,4401],[1,343],[9,54]],[[5233,4798],[-8,25],[-18,12],[0,31],[14,43],[20,38],[14,61],[13,50],[10,24],[-6,29],[-16,16],[-22,37]],[[5234,5164],[1,33],[-9,30],[-3,265],[0,243]],[[5223,5735],[94,1]],[[5790,4879],[3,-4],[0,-474]],[[5234,5164],[-197,-2],[-34,-20],[-24,9],[-19,-16],[-35,-21],[-43,3],[-22,-16],[-20,-7],[-15,10],[-34,9],[-22,-6],[-37,-21],[-23,0],[-22,7],[-7,27],[-3,32],[-18,36],[-27,11],[-23,17],[-30,1],[-21,1]],[[4558,5218],[-7,110],[-31,164],[-27,88],[11,37],[138,-64],[51,-180],[23,50],[-15,156],[-32,157],[270,0],[284,-1]],[[5443,2632],[13,-1],[10,38],[-17,26],[-3,29],[-5,33],[19,44],[7,87],[29,39],[-18,37],[-12,36],[-8,33],[-5,26],[-2,17]],[[5451,3076],[6,38],[-5,37],[-2,37],[0,41],[-9,26],[7,24],[20,0],[18,-14],[13,-7],[7,29],[4,6],[-1,153]],[[5509,3446],[154,3],[183,0],[139,-1]],[[5985,3448],[0,-1079]],[[5985,2369],[-189,-2],[-218,135],[-144,92],[9,38]],[[5443,2632],[-121,-21],[-108,-15],[-16,98],[-62,109],[-45,23],[-10,55],[-54,9],[-34,52],[-88,19],[-25,31],[-11,104],[-93,192],[-79,265],[3,44],[-42,63],[-74,160],[-13,155],[-51,104],[21,158],[-3,164]],[[4538,4401],[402,-2]],[[4940,4399],[0,-571],[179,-258],[172,-252],[160,-242]],[[6653,3446],[-92,1]],[[6561,3447],[-114,0],[-162,0],[-151,0],[-149,0]],[[5985,3447],[-1,764]],[[5984,4211],[95,0],[96,0],[191,0],[96,0]],[[6462,4211],[190,0],[0,-185],[0,-6]],[[6652,4020],[1,-294],[0,-280]],[[4940,4399],[283,1],[0,1]],[[5509,4400],[0,-954]],[[5985,2369],[0,1078]],[[6561,3447],[0,-95]],[[6561,3352],[0,-499],[0,-359],[-88,0],[-172,0],[-86,0],[1,-16],[11,-31]],[[6227,2447],[-166,0],[0,-78],[-76,0]],[[4538,4401],[-31,146],[38,180],[23,346],[-10,145]],[[5233,4798],[-8,-54],[-2,-343]],[[5984,4211],[-35,0],[-39,2],[-40,1],[-43,1],[-34,1],[0,69],[0,64],[0,52]],[[6458,4981],[3,-389]],[[6461,4592],[1,-381]],[[7777,3070],[-1,-15],[-17,-14],[-1,-28],[-12,-51],[-11,-11],[-17,-26],[-10,-39],[-21,-66],[-2,-46],[11,-50],[-5,-37]],[[7691,2687],[-81,6],[-104,-6],[-92,0]],[[7414,2687],[6,108],[-23,1],[-18,-2],[-5,12]],[[7374,2806],[3,167],[2,185],[-19,202]],[[7360,3360],[116,-3],[105,0],[101,0],[109,-12],[7,-24],[-10,-20],[-11,-21],[-6,-19],[62,0]],[[7833,3261],[-1,-16],[-9,-26],[-17,-19],[-4,-32],[-15,-25],[1,-55],[-11,-18]],[[7740,4497],[6,-14],[11,-10],[4,-21],[15,-15],[10,-16],[-5,-52],[-17,-43],[-7,-14],[-22,-11],[-32,-9],[-9,-33],[12,-15],[4,-29],[-12,-33],[-7,-29],[-24,-28],[-2,-35]],[[7665,4090],[-13,16],[-18,31],[-105,-5],[-109,-1],[-86,0],[-86,0]],[[7248,4131],[-6,34],[3,34],[-2,33],[-10,55],[-6,23],[-7,6],[-1,44],[-6,32],[-17,36],[0,16],[-6,31],[-5,19]],[[7185,4494],[1,18],[-16,21],[8,31],[5,31],[2,20],[-12,26],[0,46],[13,0]],[[7684,4687],[1,-10],[13,-31],[-9,-14],[1,-40],[4,-17],[6,-30],[31,-19],[9,-29]],[[7277,3447],[-172,0],[-172,0],[-95,-1],[-96,0],[-89,0]],[[6652,4020],[167,0],[124,0],[219,0],[132,0]],[[7294,4020],[22,-26],[13,1],[2,-28],[-13,-35],[7,-18],[12,-40]],[[7337,3874],[25,-18],[-1,-205]],[[7361,3651],[-1,-203],[-83,-1]],[[7887,3438],[-3,-19],[2,-30],[-16,-16],[-21,-20]],[[7849,3353],[-2,-18],[-6,-27],[-8,-47]],[[7360,3360],[1,87],[-1,0]],[[7360,3447],[1,204]],[[7361,3651],[1,204],[-25,19]],[[7294,4020],[-13,41],[-15,24],[-16,30],[-2,16]],[[7665,4090],[-9,-48],[9,-57],[16,-39],[18,-32],[22,-26],[9,-9],[8,-36],[1,-32],[11,-8],[18,13],[18,-31],[-5,-35],[-9,-28],[-6,-34],[13,-28],[19,-27],[11,-1],[25,-42],[10,-5],[7,-46],[-4,-29],[13,-47],[10,5],[17,-30]],[[6461,4592],[186,0],[143,0],[191,0],[25,-24],[35,-16],[8,9],[23,-1],[34,2],[25,-24],[26,-16],[4,-16],[8,-9],[16,-3]],[[7374,2806],[-41,37],[-27,21],[-22,-13],[-33,2],[-20,0],[-16,-16],[-16,-8],[-14,9],[-32,-10],[-14,32],[-15,-28],[-26,13],[-27,29],[-29,-19],[-12,46],[-45,-4],[-28,10],[-32,13],[-14,40],[-25,-13],[-16,16],[-23,20],[0,182],[0,187],[-95,0],[-96,0],[-95,0]],[[7277,3447],[83,0]],[[7691,2687],[7,-11],[-9,-28],[14,-39],[-4,-24],[12,-32],[-13,-20],[-4,-36],[-19,-30],[-8,-40],[-9,-46],[-12,-21],[4,-47],[84,-7],[90,0],[-3,-32],[-6,-31],[6,-24],[13,-22],[3,-32]],[[7837,2165],[2,-19],[1,-3]],[[7840,2143],[17,-50],[-1,-78],[20,-37],[-18,-25],[-36,28],[-36,-36],[-69,5],[-71,101],[-83,-24],[-70,45],[-59,-14]],[[7434,2058],[-7,21],[10,28],[14,25],[1,38],[-7,13],[8,45],[6,21],[9,70],[-8,26],[-11,43],[-8,44],[-6,30],[-15,21],[-6,204]],[[7434,2058],[-80,-44],[-87,-142],[-95,-82],[-52,-91],[-22,-86],[-1,-131],[5,-92],[18,-65],[-37,-5],[-68,42],[-74,59],[-27,89],[-21,134],[-56,108],[-33,112],[-48,131],[-67,76],[-78,-4],[-60,-151],[-79,58],[-50,57],[-23,105],[-32,100],[-57,83],[-49,61],[-34,67]],[[9361,4202],[-1,5],[-3,24],[20,18],[-7,16],[5,146]],[[9375,4411],[73,-3],[89,-5]],[[9537,4403],[1,-104],[-6,-28]],[[9532,4271],[-42,-9],[-55,-10],[-74,-51],[0,1]],[[9602,4305],[-3,29],[-15,22],[-7,50],[-40,-3]],[[9375,4411],[21,132]],[[9396,4543],[79,-3]],[[9475,4540],[115,-2],[10,19],[20,12],[11,-3]],[[9631,4566],[-1,-101],[32,-101],[39,-5],[-10,70],[29,-43],[-8,-54],[-64,-31],[-46,4]],[[9475,4540],[-8,19],[7,25],[3,50],[3,12],[3,45],[10,38],[8,17],[12,45],[2,31],[3,18],[18,9],[22,22],[3,24],[-7,28],[12,51],[-1,0]],[[9565,4974],[10,47],[30,10]],[[9605,5031],[14,-351],[-4,-18],[18,-29],[4,-26],[10,2]],[[9647,4609],[-16,-43]],[[9602,4305],[-70,-34]],[[9396,4543],[4,157],[-14,1],[-1,8],[6,27],[-9,50],[9,39],[-5,30],[-2,56],[4,25],[2,38]],[[9390,4974],[175,0]],[[8278,2302],[-195,-1],[-54,-11],[-2,-15],[22,-46],[-5,-38],[-7,-26]],[[8037,2165],[-85,21]],[[7952,2186],[-3,291],[17,305],[17,247],[-7,37]],[[7976,3066],[120,0],[123,-2]],[[8219,3064],[24,-237],[23,-190],[13,-59],[9,-34],[-16,-34],[-5,-61],[5,-35],[-2,-34],[-3,-31],[6,-25],[5,-22]],[[8278,2302],[14,-52],[96,-8],[155,-29],[7,-33],[12,17],[0,66],[12,7],[19,-14],[20,-4]],[[8613,2252],[17,-132],[32,-164],[42,-134],[1,-83],[45,-221],[-3,-129],[-4,-74],[-24,-116],[-29,-24],[-47,23],[-15,83],[-36,44],[-51,164],[-44,146],[-14,75],[19,126],[-26,105],[-75,160],[-37,29],[-96,-87],[-17,10],[-47,89],[-59,47],[-108,-24]],[[8219,3064],[73,-2],[51,2]],[[8343,3064],[119,-2]],[[8462,3062],[-11,-16],[-15,-36],[26,-31],[16,-12],[18,-60],[11,-34],[34,-45],[6,-24],[23,-31],[11,-46],[30,-38],[7,-44],[6,-21],[-3,-14],[17,-21],[10,-35],[0,-37],[8,-7],[17,-9]],[[8673,2501],[-45,-114],[-15,-135]],[[7777,3070],[94,0],[105,-4]],[[7952,2186],[-73,-13],[-39,-30]],[[7840,2143],[-3,22],[-3,32],[-13,22],[-6,24],[6,31],[3,32],[-90,0],[-84,7],[-4,47],[12,21],[9,46],[8,40],[19,30],[4,36],[13,20],[-12,32],[4,24],[-14,39],[9,28],[-7,11]],[[8462,3062],[9,6],[52,33],[88,-2],[44,-9],[1,-17],[10,13],[15,-32],[-1,-23],[106,-2],[107,-180]],[[8893,2849],[-48,-70],[-14,-64],[-105,-124],[-53,-90]],[[8037,4345],[0,-221],[0,-220],[-11,-53],[8,-14],[5,-33],[-1,-26],[-8,-11],[-7,-32],[-19,-41],[-14,-52],[-3,-38]],[[7987,3604],[1,-14],[-11,-27],[8,-18],[-17,-14],[-21,-16],[4,-41],[-13,-16],[-23,17],[-25,11],[-7,-19],[4,-29]],[[7740,4497],[97,0],[100,0],[73,-2],[0,1],[1,0]],[[8011,4496],[0,-1],[0,-49],[26,-101]],[[8297,4339],[-1,-172],[0,-186],[-1,-132]],[[8295,3849],[-6,-9],[8,-39],[-4,-14],[-16,0],[-15,-17],[-22,7],[-2,-37],[-14,-14],[-12,-33],[-14,-5],[-21,-57],[-19,16],[-6,23],[-17,-38],[-10,-21],[-21,23],[-22,-18],[-7,-19],[-30,29],[-20,-21],[-25,15],[0,-21],[-13,5]],[[8037,4345],[9,-13],[32,1],[26,21]],[[8104,4354],[103,-1],[90,1],[0,-15]],[[8508,3717],[2,-18],[-1,-39],[11,-30],[5,-29],[14,-25],[9,-23],[19,-3]],[[8567,3550],[-10,-15],[-28,-42],[-30,-22],[-2,-16],[-10,-20],[-25,-21],[-2,-2],[-1,-2],[-7,-16],[-15,-9],[-5,-3],[-27,-11]],[[8405,3371],[-65,-6],[-84,8],[-27,-2],[-55,5],[-56,2],[-51,1],[-60,-6],[-3,9],[-19,0],[0,-30],[-136,1]],[[8295,3849],[33,-4],[17,-19],[25,-43],[20,-13],[15,-16],[22,6],[17,-11],[21,10],[18,3],[7,-26],[18,-19]],[[8343,3064],[2,40],[20,12],[7,21],[13,23],[20,5],[22,8],[22,17],[9,17],[19,15],[-1,14],[24,26],[8,-17],[35,36],[16,-4],[15,32],[20,8],[-2,28],[3,24]],[[8595,3369],[161,-9],[190,-1],[101,2],[90,1],[12,0]],[[9149,3362],[14,-191],[-61,-141],[-99,-57],[-62,-112],[-48,-12]],[[8297,4339],[48,2],[44,0],[36,2]],[[8425,4343],[59,-40],[47,-10],[69,26],[57,52],[49,26]],[[8706,4397],[0,-255]],[[8706,4142],[-14,-10],[4,-24],[-4,-44],[-10,-50],[-9,-41],[-2,-19],[-26,-44],[-11,-9],[-13,-6],[-11,5],[-21,-33],[-4,-34],[-3,-19],[-9,-8],[-1,22],[-13,4],[-13,-41],[-2,-42],[-12,-27],[-24,-5]],[[8405,3371],[142,-6],[11,1],[37,3]],[[7609,5299],[96,40],[58,-65]],[[7763,5274],[0,-1],[6,4],[15,-7],[8,-34],[84,-34],[55,-34],[27,-1],[18,-2],[5,-31],[23,-12],[8,-27],[-5,-15],[-5,-31],[21,-2],[-7,-31],[13,-22],[2,-1]],[[8031,4993],[0,-2],[-38,-69],[13,-23],[70,123],[15,1],[-50,-147],[-22,-133],[-18,-108],[12,-93],[-2,-46]],[[8805,3966],[-1,-97],[15,18]],[[8972,3890],[-10,-35],[-5,4],[-44,47],[-2,-11],[-6,-40],[-8,-13],[-3,-6],[-8,-10],[-11,-14],[-14,-25],[-7,8],[-4,-10],[-7,-17],[-9,-24],[-5,-17],[-13,-8],[-15,14],[-12,15],[-9,-42],[-8,-15],[-9,-19],[-4,-28],[-19,-25],[-13,-33],[2,-22],[-1,-7],[-1,-11],[-15,-14],[-14,2],[-12,-13],[-10,6],[-1,-6],[-1,-11],[-6,-2],[-30,-14],[-11,14],[-9,-6],[-22,-17],[-14,15],[-2,4],[-9,13],[-4,33]],[[8706,4142],[0,-176],[99,0]],[[9157,3967],[7,15],[9,8],[20,-9]],[[9193,3981],[-14,-20],[3,-37]],[[9182,3924],[20,-103],[23,-34],[2,-63]],[[9193,3981],[20,17],[7,12],[22,25],[13,21],[-30,49],[-2,20],[-10,6],[0,31],[11,23],[-5,25],[15,17],[17,43],[12,8]],[[9263,4278],[73,-75],[-4,-40]],[[9332,4163],[-29,-53],[28,-9],[-21,-137],[-69,-147],[-7,49],[-21,10],[-31,48]],[[9361,4202],[-6,-5],[140,36],[28,-36],[-133,-57],[-61,-1],[3,24]],[[9263,4278],[-16,14],[-16,13],[-6,27],[2,21],[-11,18],[-21,30],[-129,0],[-139,0],[-149,0],[0,52]],[[8778,4453],[82,113],[-2,19],[-8,57],[45,22],[75,-7],[78,-16],[71,63],[-5,74],[-10,27],[98,133],[43,35],[145,1]],[[8706,4397],[72,55],[0,1]],[[9605,5031],[41,30],[34,86],[29,149],[73,144],[31,-51],[64,33],[43,-55],[0,-260],[62,-108],[17,-62],[-102,-93],[-98,-66],[-101,-56],[-51,-113]],[[8104,4354],[19,27],[39,93],[3,125],[-32,118],[5,81],[25,94],[24,64],[38,45],[9,-63],[16,94],[22,19],[13,73],[81,-39],[71,-74],[7,-87],[-8,-86],[-53,-77],[5,-48],[19,-1],[59,84],[35,-20],[18,-110],[4,-78],[-45,-105],[-20,-67],[-33,-73]],[[8031,4993],[-2,1],[-13,22],[7,31],[-21,2],[5,31],[5,15],[-8,27],[-23,12],[-5,31],[-18,2],[-27,1],[-55,34],[-84,34],[-8,34],[-15,7],[-6,-4],[0,1],[0,-1]],[[7763,5273],[74,49],[77,62],[84,63],[-31,-101],[54,-24],[67,-73],[85,43],[94,16],[20,-53],[29,-8],[6,19],[-6,-19],[25,-6],[48,-76],[-84,-17],[-3,1],[-75,20],[-75,-38],[-65,-17],[-56,-121]],[[1791,7283],[-95,-73],[-49,50],[-14,89],[86,68],[51,29],[63,-13],[41,-59],[-83,-91]],[[592,7816],[-58,-30],[-63,36],[-58,52],[94,32],[76,-17],[9,-73]],[[5,8554],[59,-36],[60,19],[77,-50],[94,-25],[-8,-21],[-72,-40],[-72,41],[-37,35],[-84,-11],[-22,16],[5,72]],[[1595,9958],[69,-86],[42,37],[161,-11],[-5,-44],[145,-32],[98,19],[201,-61],[183,-18],[74,-24],[127,31],[144,-58],[104,-26],[-1,-708],[0,-1086],[94,-5],[93,-53],[66,-84],[85,-125],[93,107],[95,61],[51,-98],[64,-78],[88,-86],[59,-137],[98,-217],[162,-122],[3,-120],[-53,-92],[-53,72],[-84,60],[-27,167],[-123,154],[-51,180],[-92,12],[-151,5],[-112,55],[-197,198],[-92,36],[-167,68],[-132,-16],[-187,87],[-114,82],[-106,-41],[20,-132],[-53,-12],[-110,-40],[-84,-65],[-106,-40],[-13,112],[43,187],[101,59],[-26,48],[-122,-106],[-65,-127],[-137,-136],[69,-93],[-90,-137],[-102,-79],[-96,-58],[-23,-85],[-149,-98],[-30,-90],[-112,-81],[-65,14],[-89,-53],[-97,-65],[-80,-64],[-163,-54],[-15,32],[104,89],[93,59],[102,104],[118,22],[47,78],[133,114],[21,38],[70,68],[17,144],[48,113],[-110,-58],[-30,33],[-52,-70],[-62,97],[-26,-68],[-36,95],[-95,-77],[-59,1],[-8,113],[17,70],[-61,68],[-124,-37],[-81,90],[-65,46],[0,108],[-74,81],[37,110],[78,106],[34,98],[77,14],[66,-31],[77,92],[69,-16],[73,59],[-18,87],[-54,34],[71,74],[-59,-2],[-101,-42],[-29,-42],[-75,42],[-135,-21],[-140,46],[-40,76],[-120,111],[134,80],[212,93],[79,0],[-13,-95],[201,7],[-77,118],[-118,73],[-67,95],[-92,81],[-131,61],[53,100],[170,6],[120,87],[23,93],[97,90],[93,22],[181,85],[88,-13],[146,102],[145,-41]],[[9030,3816],[3,-6],[2,-5],[3,-5],[0,-5],[-1,-6]],[[9042,3684],[66,-61],[4,-182],[27,-13],[10,-66]],[[9163,3626],[-29,-130],[8,-7],[54,152]],[[5984,4211],[1,-763]]]} -------------------------------------------------------------------------------- /source/data/src/world/countries.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "004":"Afghanistan", 3 | "008":"Albania", 4 | "010":"Antarctica", 5 | "012":"Algeria", 6 | "016":"American Samoa", 7 | "020":"Andorra", 8 | "024":"Angola", 9 | "028":"Antigua and Barbuda", 10 | "031":"Azerbaijan", 11 | "032":"Argentina", 12 | "036":"Australia", 13 | "040":"Austria", 14 | "044":"Bahamas", 15 | "048":"Bahrain", 16 | "050":"Bangladesh", 17 | "051":"Armenia", 18 | "052":"Barbados", 19 | "056":"Belgium", 20 | "060":"Bermuda", 21 | "064":"Bhutan", 22 | "068":"Bolivia", 23 | "070":"Bosnia and Herzegovina", 24 | "072":"Botswana", 25 | "074":"Bouvet Island", 26 | "076":"Brazil", 27 | "084":"Belize", 28 | "086":"British Indian Ocean Territory", 29 | "090":"Solomon Islands", 30 | "092":"Virgin Islands, British", 31 | "096":"Brunei Darussalam", 32 | "100":"Bulgaria", 33 | "104":"Myanmar", 34 | "108":"Burundi", 35 | "112":"Belarus", 36 | "116":"Cambodia", 37 | "120":"Cameroon", 38 | "124":"Canada", 39 | "132":"Cabo Verde", 40 | "136":"Cayman Islands", 41 | "140":"Central African Republic", 42 | "144":"Sri Lanka", 43 | "148":"Chad", 44 | "152":"Chile", 45 | "156":"China", 46 | "158":"Taiwan", 47 | "162":"Christmas Island", 48 | "166":"Cocos (Keeling) Islands", 49 | "170":"Colombia", 50 | "174":"Comoros", 51 | "175":"Mayotte", 52 | "178":"Congo", 53 | "180":"Democratic Republic of the Congo", 54 | "184":"Cook Islands", 55 | "188":"Costa Rica", 56 | "191":"Croatia", 57 | "192":"Cuba", 58 | "196":"Cyprus", 59 | "203":"Czech Republic", 60 | "204":"Benin", 61 | "208":"Denmark", 62 | "212":"Dominica", 63 | "214":"Dominican Republic", 64 | "218":"Ecuador", 65 | "222":"El Salvador", 66 | "226":"Equatorial Guinea", 67 | "231":"Ethiopia", 68 | "232":"Eritrea", 69 | "233":"Estonia", 70 | "234":"Faroe Islands", 71 | "238":"Falkland Islands", 72 | "239":"South Georgia and the South Sandwich Islands", 73 | "242":"Fiji", 74 | "246":"Finland", 75 | "248":"Åland Islands", 76 | "250":"France", 77 | "254":"French Guiana", 78 | "258":"French Polynesia", 79 | "260":"French Southern Territories", 80 | "262":"Djibouti", 81 | "266":"Gabon", 82 | "268":"Georgia", 83 | "270":"Gambia", 84 | "275":"Palestine", 85 | "276":"Germany", 86 | "288":"Ghana", 87 | "292":"Gibraltar", 88 | "296":"Kiribati", 89 | "300":"Greece", 90 | "304":"Greenland", 91 | "308":"Grenada", 92 | "312":"Guadeloupe", 93 | "316":"Guam", 94 | "320":"Guatemala", 95 | "324":"Guinea", 96 | "328":"Guyana", 97 | "332":"Haiti", 98 | "334":"Heard Island and McDonald Islands", 99 | "336":"Holy See", 100 | "340":"Honduras", 101 | "344":"Hong Kong", 102 | "348":"Hungary", 103 | "352":"Iceland", 104 | "356":"India", 105 | "360":"Indonesia", 106 | "364":"Iran", 107 | "368":"Iraq", 108 | "372":"Ireland", 109 | "376":"Israel", 110 | "380":"Italy", 111 | "384":"Côte d'Ivoire", 112 | "388":"Jamaica", 113 | "392":"Japan", 114 | "398":"Kazakhstan", 115 | "400":"Jordan", 116 | "404":"Kenya", 117 | "408":"North Korea", 118 | "410":"South Korea", 119 | "414":"Kuwait", 120 | "417":"Kyrgyzstan", 121 | "418":"Laos", 122 | "422":"Lebanon", 123 | "426":"Lesotho", 124 | "428":"Latvia", 125 | "430":"Liberia", 126 | "434":"Libya", 127 | "438":"Liechtenstein", 128 | "440":"Lithuania", 129 | "442":"Luxembourg", 130 | "446":"Macao", 131 | "450":"Madagascar", 132 | "454":"Malawi", 133 | "458":"Malaysia", 134 | "462":"Maldives", 135 | "466":"Mali", 136 | "470":"Malta", 137 | "474":"Martinique", 138 | "478":"Mauritania", 139 | "480":"Mauritius", 140 | "484":"Mexico", 141 | "492":"Monaco", 142 | "496":"Mongolia", 143 | "498":"Moldova", 144 | "499":"Montenegro", 145 | "500":"Montserrat", 146 | "504":"Morocco", 147 | "508":"Mozambique", 148 | "512":"Oman", 149 | "516":"Namibia", 150 | "520":"Nauru", 151 | "524":"Nepal", 152 | "528":"Netherlands", 153 | "531":"Curaçao", 154 | "533":"Aruba", 155 | "534":"Sint Maarten", 156 | "535":"Bonaire", 157 | "540":"New Caledonia", 158 | "548":"Vanuatu", 159 | "554":"New Zealand", 160 | "558":"Nicaragua", 161 | "562":"Niger", 162 | "566":"Nigeria", 163 | "570":"Niue", 164 | "574":"Norfolk Island", 165 | "578":"Norway", 166 | "580":"Northern Mariana Islands", 167 | "581":"United States Minor Outlying Islands", 168 | "583":"Micronesia", 169 | "584":"Marshall Islands", 170 | "585":"Palau", 171 | "586":"Pakistan", 172 | "591":"Panama", 173 | "598":"Papua New Guinea", 174 | "600":"Paraguay", 175 | "604":"Peru", 176 | "608":"Philippines", 177 | "612":"Pitcairn", 178 | "616":"Poland", 179 | "620":"Portugal", 180 | "624":"Guinea-Bissau", 181 | "626":"Timor-Leste", 182 | "630":"Puerto Rico", 183 | "634":"Qatar", 184 | "638":"Réunion", 185 | "642":"Romania", 186 | "643":"Russian Federation", 187 | "646":"Rwanda", 188 | "652":"Saint Barthélemy", 189 | "654":"Saint Helena", 190 | "659":"Saint Kitts and Nevis", 191 | "660":"Anguilla", 192 | "662":"Saint Lucia", 193 | "663":"Saint Martin", 194 | "666":"Saint Pierre and Miquelon", 195 | "670":"Saint Vincent and the Grenadines", 196 | "674":"San Marino", 197 | "678":"Sao Tome and Principe", 198 | "682":"Saudi Arabia", 199 | "686":"Senegal", 200 | "688":"Serbia", 201 | "690":"Seychelles", 202 | "694":"Sierra Leone", 203 | "702":"Singapore", 204 | "703":"Slovakia", 205 | "704":"Viet Nam", 206 | "705":"Slovenia", 207 | "706":"Somalia", 208 | "710":"South Africa", 209 | "716":"Zimbabwe", 210 | "724":"Spain", 211 | "728":"South Sudan", 212 | "729":"Sudan", 213 | "732":"Western Sahara", 214 | "740":"Suriname", 215 | "744":"Svalbard and Jan Mayen", 216 | "748":"Swaziland", 217 | "752":"Sweden", 218 | "756":"Switzerland", 219 | "760":"Syrian Arab Republic", 220 | "762":"Tajikistan", 221 | "764":"Thailand", 222 | "768":"Togo", 223 | "772":"Tokelau", 224 | "776":"Tonga", 225 | "780":"Trinidad and Tobago", 226 | "784":"United Arab Emirates", 227 | "788":"Tunisia", 228 | "792":"Turkey", 229 | "795":"Turkmenistan", 230 | "796":"Turks and Caicos Islands", 231 | "798":"Tuvalu", 232 | "800":"Uganda", 233 | "804":"Ukraine", 234 | "807":"Macedonia", 235 | "818":"Egypt", 236 | "826":"United Kingdom", 237 | "831":"Guernsey", 238 | "832":"Jersey", 239 | "833":"Isle of Man", 240 | "834":"Tanzania", 241 | "840":"United States", 242 | "850":"Virgin Islands", 243 | "854":"Burkina Faso", 244 | "858":"Uruguay", 245 | "860":"Uzbekistan", 246 | "862":"Venezuela", 247 | "876":"Wallis and Futuna", 248 | "882":"Samoa", 249 | "887":"Yemen", 250 | "894":"Zambia" 251 | } -------------------------------------------------------------------------------- /source/data/src/world/parser.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var world = require('./world'); 3 | var countries = require('./countries'); 4 | var geos = world.objects.countries.geometries; 5 | 6 | var parsed = []; 7 | 8 | for (var i = 0; i < geos.length; i++) { 9 | geo = geos[i]; 10 | var id = ('000'+String(geo.id)).slice(-3); 11 | delete geo.id; 12 | 13 | // Omit missing country names and Antarctica 14 | if (countries[id] && id !== '010') { 15 | geo.properties = {id: id, name: countries[id]}; 16 | parsed.push(geo); 17 | } 18 | } 19 | 20 | world.objects.countries.geometries = parsed; 21 | fs.writeFile('./world.json', JSON.stringify(world)); -------------------------------------------------------------------------------- /source/data/us-state.json: -------------------------------------------------------------------------------- 1 | {"type":"Topology","transform":{"scale":[0.0036432214697640418,0.0022584397799407536],"translate":[-179.069176,17.929406]},"objects":{"states":{"type":"GeometryCollection","geometries":[{"arcs":[[0,1,2,3,4]],"type":"Polygon","properties":{"id":"01","name":"Alabama"}},{"arcs":[[[5]],[[6]],[[7]],[[8]],[[9]],[[10]],[[11]],[[12]],[[13]],[[14]],[[15]],[[16]],[[17]],[[18]],[[19]],[[20]],[[21]],[[22]],[[23]],[[24]],[[25]],[[26]],[[27]],[[28]],[[29]],[[30]],[[31]],[[32]],[[33]],[[34]],[[35]],[[36]],[[37]],[[38]],[[39]],[[40]],[[41]],[[42]],[[43]],[[44]],[[45]],[[46]]],"type":"MultiPolygon","properties":{"id":"02","name":"Alaska"}},{"arcs":[[47,48,49,50,51]],"type":"Polygon","properties":{"id":"04","name":"Arizona"}},{"arcs":[[52,53,54,55,56,57]],"type":"Polygon","properties":{"id":"05","name":"Arkansas"}},{"arcs":[[[58]],[[59]],[[60,-50,61,62]]],"type":"MultiPolygon","properties":{"id":"06","name":"California"}},{"arcs":[[63,64,65,66,67,68]],"type":"Polygon","properties":{"id":"08","name":"Colorado"}},{"arcs":[[69,70,71,72]],"type":"Polygon","properties":{"id":"09","name":"Connecticut"}},{"arcs":[[75,76,77,78]],"type":"Polygon","properties":{"id":"10","name":"Delaware"}},{"arcs":[[79,80]],"type":"Polygon","properties":{"id":"11","name":"District of Columbia"}},{"arcs":[[[81]],[[82,-2,83]]],"type":"MultiPolygon","properties":{"id":"12","name":"Florida"}},{"arcs":[[84,85,86,-84,-1,87]],"type":"Polygon","properties":{"id":"13","name":"Georgia"}},{"arcs":[[[88]],[[89]],[[90]],[[91]],[[92]],[[93]]],"type":"MultiPolygon","properties":{"id":"15","name":"Hawaii"}},{"arcs":[[94,95,96,97,98,99,100]],"type":"Polygon","properties":{"id":"16","name":"Idaho"}},{"arcs":[[101,102,103,104,105,106]],"type":"Polygon","properties":{"id":"17","name":"Illinois"}},{"arcs":[[107,-103,108,109,110]],"type":"Polygon","properties":{"id":"18","name":"Indiana"}},{"arcs":[[111,-106,112,113,114,115]],"type":"Polygon","properties":{"id":"19","name":"Iowa"}},{"arcs":[[-65,116,117,118]],"type":"Polygon","properties":{"id":"20","name":"Kansas"}},{"arcs":[[121,122,123,-104,-108,124,125]],"type":"Polygon","properties":{"id":"21","name":"Kentucky"}},{"arcs":[[126,-58,127,128]],"type":"Polygon","properties":{"id":"22","name":"Louisiana"}},{"arcs":[[[129]],[[130,131]]],"type":"MultiPolygon","properties":{"id":"23","name":"Maine"}},{"arcs":[[-81,134,135,136,-78,137,138,139,140]],"type":"Polygon","properties":{"id":"24","name":"Maryland"}},{"arcs":[[[141]],[[142,143,144,145,146,-73,147,148]]],"type":"MultiPolygon","properties":{"id":"25","name":"Massachusetts"}},{"arcs":[[[149]],[[150]],[[-110,151,152]],[[153,154]]],"type":"MultiPolygon","properties":{"id":"26","name":"Michigan"}},{"arcs":[[-116,155,156,157,158]],"type":"Polygon","properties":{"id":"27","name":"Minnesota"}},{"arcs":[[159,-4,160,-128,-57]],"type":"Polygon","properties":{"id":"28","name":"Mississippi"}},{"arcs":[[-55,161,-118,162,-113,-105,-124,163,-121,164]],"type":"Polygon","properties":{"id":"29","name":"Missouri"}},{"arcs":[[-100,165,166,167,168]],"type":"Polygon","properties":{"id":"30","name":"Montana"}},{"arcs":[[169,170,-114,-163,-117,-64]],"type":"Polygon","properties":{"id":"31","name":"Nebraska"}},{"arcs":[[-51,-61,171,-96,172]],"type":"Polygon","properties":{"id":"32","name":"Nevada"}},{"arcs":[[173,-131,174,-143,175]],"type":"Polygon","properties":{"id":"33","name":"New Hampshire"}},{"arcs":[[176,177,-75,178,-76,179]],"type":"Polygon","properties":{"id":"34","name":"New Jersey"}},{"arcs":[[180,-48,-67,181,182]],"type":"Polygon","properties":{"id":"35","name":"New Mexico"}},{"arcs":[[183,-148,-72,184,-177,185,186]],"type":"Polygon","properties":{"id":"36","name":"New York"}},{"arcs":[[[187]],[[188,189,-85,190,191]]],"type":"MultiPolygon","properties":{"id":"37","name":"North Carolina"}},{"arcs":[[-167,192,-157,193]],"type":"Polygon","properties":{"id":"38","name":"North Dakota"}},{"arcs":[[-125,-111,-153,194,195,196]],"type":"Polygon","properties":{"id":"39","name":"Ohio"}},{"arcs":[[-182,-66,-119,-162,-54,197]],"type":"Polygon","properties":{"id":"40","name":"Oklahoma"}},{"arcs":[[-97,-172,-63,198,199]],"type":"Polygon","properties":{"id":"41","name":"Oregon"}},{"arcs":[[-196,200,-186,-180,-79,-137,201]],"type":"Polygon","properties":{"id":"42","name":"Pennsylvania"}},{"arcs":[[[202,-145]],[[-147,203,-70]]],"type":"MultiPolygon","properties":{"id":"44","name":"Rhode Island"}},{"arcs":[[-86,-190,204]],"type":"Polygon","properties":{"id":"45","name":"South Carolina"}},{"arcs":[[-168,-194,-156,-115,-171,205]],"type":"Polygon","properties":{"id":"46","name":"South Dakota"}},{"arcs":[[-191,-88,-5,-160,-56,-165,-120,-164,-123,206]],"type":"Polygon","properties":{"id":"47","name":"Tennessee"}},{"arcs":[[-183,-198,-53,-127,207]],"type":"Polygon","properties":{"id":"48","name":"Texas"}},{"arcs":[[-68,-52,-173,-95,208]],"type":"Polygon","properties":{"id":"49","name":"Utah"}},{"arcs":[[-149,-184,209,-176]],"type":"Polygon","properties":{"id":"50","name":"Vermont"}},{"arcs":[[[211,-139]],[[212,-192,-207,-122,213,-135,-80,-141]]],"type":"MultiPolygon","properties":{"id":"51","name":"Virginia"}},{"arcs":[[[214]],[[215]],[[216]],[[-98,-200,217]]],"type":"MultiPolygon","properties":{"id":"53","name":"Washington"}},{"arcs":[[-136,-214,-126,-197,-202]],"type":"Polygon","properties":{"id":"54","name":"West Virginia"}},{"arcs":[[-107,-112,-159,218,-155,219]],"type":"Polygon","properties":{"id":"55","name":"Wisconsin"}},{"arcs":[[-101,-169,-206,-170,-69,-209]],"type":"Polygon","properties":{"id":"56","name":"Wyoming"}},{"arcs":[[220]],"type":"Polygon","properties":{"id":"72","name":"Puerto Rico"}}]}},"arcs":[[[25654,7552],[37,-291],[31,-256],[33,-275],[19,-139],[10,-16],[18,-88],[26,-61],[-8,-53],[29,-25],[-46,-59],[2,-54],[-23,-67],[4,-73],[23,-68],[-20,-123],[4,-43],[18,-26],[9,-47]],[[25820,5788],[-245,-3],[-172,-1],[-296,2],[-10,-58],[28,-54],[35,-30],[-11,-66],[4,-53],[-24,-56]],[[25129,5469],[-38,-14],[-27,19],[-41,52],[1,63],[-10,47],[-19,12],[-26,-78],[-2,-58],[-79,-4]],[[24888,5508],[-12,389],[-9,286],[19,246],[20,276],[33,424],[31,382],[-28,46]],[[24942,7557],[-1,5],[368,-7],[345,-3]],[[4615,16405],[6,-39],[-32,-24],[-24,40],[50,23]],[[5229,16483],[41,-27],[-72,-36],[-15,47],[46,16]],[[5095,16559],[6,-59],[-98,5],[-4,50],[40,38],[56,-34]],[[3645,16048],[6,-47],[-76,-10],[-19,35],[36,43],[53,-21]],[[3718,16104],[13,-52],[-42,-22],[-13,59],[42,15]],[[4465,16188],[59,-17],[-7,-37],[-68,26],[16,28]],[[633,15027],[-13,27],[49,19],[15,-57],[79,13],[0,-57],[-63,7],[-18,-30],[-76,-3],[-12,57],[39,24]],[[348,14988],[-44,-26],[-70,61],[25,28],[48,-3],[41,-60]],[[469,14965],[41,38],[3,50],[43,-12],[-26,-37],[4,-38],[-38,-21],[-27,20]],[[97900,15093],[-11,-44],[-42,6],[-32,-37],[-25,21],[40,31],[70,23]],[[98492,15062],[-40,-33],[-36,49],[50,18],[26,-34]],[[837,15095],[-44,-9],[-9,29],[42,18],[11,-38]],[[1309,15209],[-7,44],[39,18],[32,-12],[22,-42],[-43,-76],[-52,-4],[-33,-24],[-78,-24],[-28,37],[50,8],[36,29],[33,4],[29,42]],[[1501,15154],[24,-20],[107,0],[4,-13],[-121,-22],[-69,34],[55,21]],[[1767,15204],[17,37],[33,18],[41,-27],[-63,-33],[-28,5]],[[96572,15451],[-34,45],[-3,33],[131,-3],[52,-30],[35,-36],[-143,-37],[-38,28]],[[2980,15642],[-78,-98],[-127,-66],[55,87],[-1,45],[40,34],[70,-4],[-12,42],[17,57],[39,26],[54,14],[61,-28],[-16,-51],[-102,-58]],[[3387,15973],[46,-55],[34,34],[44,12],[18,-22],[-57,-76],[82,41],[3,-34],[-47,-41],[-75,-27],[-7,-41],[-42,-11],[-40,-34],[-70,-1],[-140,-78],[-57,28],[43,32],[65,25],[28,-8],[70,40],[12,81],[74,16],[-97,41],[30,52],[83,26]],[[3664,18703],[40,-117],[-49,-2],[-124,-48],[-64,29],[-49,-3],[-104,63],[-38,1],[-57,35],[-22,54],[30,19],[103,-15],[48,46],[109,22],[52,19],[25,-34],[55,8],[47,-14],[-2,-63]],[[1651,18856],[41,9],[33,-34],[115,-55],[-63,-7],[-126,87]],[[4982,18073],[64,31],[-54,-104],[-53,-14],[5,68],[38,19]],[[13127,16410],[-6,-58],[-24,0],[-35,41],[65,17]],[[12986,16583],[30,-33],[-27,-79],[-32,71],[29,41]],[[13038,16540],[47,-32],[13,-64],[-11,-24],[-70,10],[27,48],[-6,62]],[[12551,16666],[10,-37],[-31,-44],[-43,-27],[-16,46],[-29,19],[2,39],[69,-21],[38,25]],[[12617,16603],[-20,71],[-24,-8],[-120,93],[87,43],[-43,45],[-49,-37],[-22,14],[29,64],[40,32],[-25,25],[-7,50],[22,18],[115,-15],[26,-35],[4,-51],[115,-90],[45,-61],[3,-44],[28,-15],[31,-69],[-20,-11],[53,-80],[40,-34],[6,-186],[-20,-40],[-30,-4],[-129,121],[-84,35],[8,-66],[43,19],[28,-24],[4,-47],[-17,-43],[-52,9],[-71,106],[-32,67],[5,61],[-60,-8],[-3,48],[92,25],[4,22]],[[8743,18758],[59,-27],[-55,-36],[-80,-87],[14,-18],[-119,-58],[-5,38],[25,30],[102,71],[59,87]],[[8648,18885],[-15,-94],[-39,-94],[-54,32],[45,110],[63,46]],[[12651,17052],[67,8],[31,-30],[-11,-51],[-59,-16],[-52,42],[24,47]],[[12175,17840],[94,-31],[42,5],[86,-157],[-35,5],[-31,-26],[57,-64],[22,-67],[-4,-47],[-45,-13],[-33,-53],[-94,-78],[-28,1],[-13,85],[50,73],[-39,54],[-34,92],[7,48],[-25,102],[-32,69],[-15,67],[67,-44],[3,-21]],[[7363,17849],[-6,-46],[-59,-3],[-48,-30],[-94,32],[-21,-15],[35,-52],[-128,39],[52,40],[49,64],[57,30],[51,59],[-4,26],[90,10],[-48,-71],[5,-32],[140,-2],[0,-61],[-26,-26],[-45,38]],[[6770,17110],[-63,-44],[-20,22],[47,35],[36,-13]],[[6897,17104],[-3,-22],[-77,-8],[-16,47],[54,10],[42,-27]],[[7315,17661],[-21,-34],[9,-59],[54,9],[28,-18],[-54,-70],[-66,18],[0,-38],[-26,-45],[-68,-9],[9,-59],[-113,-40],[-45,22],[-56,-95],[-45,-16],[-19,-30],[-41,32],[61,52],[-62,6],[-41,-42],[-82,51],[-4,91],[-56,52],[31,87],[111,67],[67,-6],[46,-27],[-33,100],[59,34],[41,-26],[32,58],[49,-32],[40,25],[70,-6],[41,-43],[48,28],[36,-37]],[[12337,16888],[-30,-1],[-4,89],[-13,37],[27,26],[42,5],[-65,72],[-33,62],[-6,50],[37,30],[32,-24],[24,36],[55,-94],[34,-20],[12,-37],[-37,-8],[-23,-88],[27,-23],[-28,-69],[-46,6],[-5,-49]],[[12770,17126],[-75,-50],[-61,11],[-45,-32],[-59,21],[-26,-25],[-41,4],[0,67],[-13,38],[9,56],[-52,16],[-15,51],[-35,30],[44,30],[152,-42],[63,1],[30,-28],[17,-53],[107,-95]],[[12188,16932],[-39,29],[-101,196],[-27,11],[-38,48],[22,46],[5,58],[-30,54],[-35,29],[-38,60],[37,26],[37,61],[97,-65],[60,-4],[2,-71],[57,-230],[-10,-83],[9,-122],[-8,-43]],[[11935,17697],[71,-66],[112,-2],[26,-108],[-71,-15],[-134,92],[6,-85],[-39,-47],[-55,14],[-65,96],[-21,6],[-43,85],[-58,43],[5,67],[52,32],[-9,54],[116,-31],[53,38],[91,-68],[94,-20],[54,-49],[-25,-42],[-5,-46],[-48,-2],[-107,54]],[[11903,17442],[35,-100],[-16,-32],[-61,-11],[5,151],[37,-8]],[[4524,20079],[87,93],[67,-17],[121,0],[123,25],[102,119],[0,27],[-51,113],[-7,65],[-79,72],[-66,11],[32,48],[100,-14],[61,49],[5,47],[-42,46],[-76,27],[-45,-48],[-79,7],[-58,-36],[-80,-12],[-18,-27],[-84,-40],[-25,-64],[-49,-15],[-13,66],[-99,58],[-26,-19],[16,-53],[-94,42],[-64,5],[-163,-13],[-105,-43],[-58,-6],[-109,28],[-226,38],[-42,24],[-26,42],[19,61],[-75,51],[14,56],[48,28],[32,44],[-38,25],[-85,2],[-64,20],[-122,14],[-65,38],[-100,34],[-8,49],[155,60],[195,102],[281,124],[109,39],[191,54],[85,17],[116,6],[62,-19],[-2,-43],[-31,-29],[12,-52],[-24,-36],[41,-57],[75,11],[89,-12],[115,14],[35,-23],[64,-4],[74,17],[78,-20],[79,96],[57,7],[39,-20],[55,20],[-36,36],[-109,27],[-107,-21],[12,71],[-83,78],[-89,25],[-28,69],[70,16],[92,-78],[-16,-50],[42,-42],[94,-50],[68,18],[-152,105],[5,36],[52,73],[-38,39],[-117,-25],[-182,6],[-186,38],[-45,16],[-5,56],[-33,71],[-55,75],[-124,62],[-264,148],[-82,9],[-158,89],[-93,40],[91,22],[39,63],[5,140],[244,-10],[295,33],[76,24],[121,69],[116,103],[53,141],[-26,29],[146,96],[46,59],[107,81],[80,-22],[104,7],[143,52],[142,82],[156,104],[120,33],[13,-23],[139,-13],[171,20],[146,51],[69,46],[121,104],[76,4],[126,-24],[32,-25],[101,-6],[11,-49],[-128,-73],[38,-30],[102,14],[8,37],[60,61],[62,29],[127,-70],[-21,-53],[80,-15],[47,-30],[80,52],[128,2],[51,14],[178,-15],[91,-20],[-44,-103],[165,-28],[72,-49],[103,-2],[115,29],[111,-1],[67,-28],[68,35],[188,-11],[107,-37],[49,9],[71,-52],[41,19],[106,-31],[37,-34],[190,-24],[29,17],[168,-4],[132,-12],[46,-29],[117,-39],[159,-12],[43,25],[105,15],[46,31],[114,5],[206,-43],[94,-56],[90,-28],[18,-23],[82,-5],[77,-42],[118,-22],[0,-508],[0,-1177],[0,-1645],[0,-198],[0,-607],[128,-37],[17,39],[133,-56],[80,69],[167,8],[-31,-119],[47,-43],[90,-37],[22,-61],[279,-234],[43,-148],[51,41],[120,70],[67,2],[32,53],[-2,80],[47,0],[12,71],[86,17],[128,60],[61,-43],[63,-61],[-11,-63],[29,-62],[71,-15],[6,-25],[55,-28],[22,-67],[41,-52],[113,-58],[38,-54],[88,-79],[-22,-19],[78,-104],[27,-67],[57,-69],[85,-150],[53,-69],[31,-59],[-32,-53],[88,-20],[-21,-78],[54,-17],[26,-103],[70,5],[32,-29],[104,-63],[83,-17],[44,-44],[42,-13],[12,-44],[49,-19],[39,9],[24,-44],[-2,-45],[-35,-66],[7,-82],[40,-132],[-32,-38],[-25,-59],[-42,-64],[-97,-89],[-13,37],[-48,-6],[-26,92],[8,32],[-49,57],[-73,18],[-75,51],[-40,45],[0,29],[50,27],[-45,38],[-44,-74],[-54,39],[-11,50],[11,44],[27,14],[-20,40],[-66,12],[-34,56],[-51,16],[-3,46],[33,10],[19,44],[52,1],[-15,64],[27,85],[-42,-2],[-29,37],[-59,36],[-27,39],[-13,51],[-111,32],[-54,29],[-7,28],[25,51],[-20,59],[5,39],[-46,21],[6,39],[-54,98],[-55,56],[-10,53],[-115,15],[-35,14],[-39,67],[-5,41],[-41,54],[-57,103],[-16,102],[-46,6],[-5,-52],[69,-157],[-13,-18],[39,-118],[-11,-49],[-52,15],[-33,42],[-64,44],[-76,-21],[-1,106],[-49,87],[-43,-28],[-105,61],[145,-167],[16,-59],[-95,-37],[-43,9],[-13,-44],[-30,1],[-67,77],[-45,-1],[-157,102],[-1,19],[-67,51],[-1,39],[-51,68],[-142,48],[-78,52],[-137,59],[-120,69],[36,45],[38,2],[2,58],[-34,71],[-29,-46],[-131,-58],[-119,9],[-57,12],[-136,58],[34,26],[4,35],[-85,-24],[-259,54],[-102,3],[-217,-28],[-54,-18],[-38,15],[-111,-35],[91,70],[-150,47],[-35,38],[-44,-1],[30,69],[-69,-4],[12,-35],[-59,-20],[-93,62],[-88,18],[-60,-27],[-18,-31],[-80,-29],[-55,-5],[-8,50],[23,31],[50,-1],[180,57],[-60,33],[-69,-9],[-119,42],[40,30],[-55,30],[3,35],[-62,-10],[-45,21],[-66,-46],[-106,16],[9,-43],[-115,5],[23,48],[-59,-8],[-24,-68],[60,-3],[17,-72],[40,-67],[-23,-73],[-34,20],[-49,-28],[65,-20],[76,-70],[-61,-45],[-60,0],[-40,18],[-65,-26],[-64,5],[-92,26],[-83,-20],[-21,-43],[-44,-2],[5,-75],[-57,-10],[-99,-95],[-61,3],[-61,-16],[-47,-51],[-9,-34],[-99,-11],[-37,20],[-42,-41],[-43,-1],[-63,42],[25,74],[69,27],[45,-5],[55,37],[43,99],[-107,-64],[-89,38],[-11,26],[46,112],[77,80],[11,65],[22,12],[10,70],[-40,78],[95,30],[98,66],[90,45],[32,-40],[61,-12],[74,21],[8,21],[-92,62],[42,24],[104,124],[-91,-47],[-12,-53],[-151,-9],[-66,3],[-86,-32],[-39,-59],[-86,-15],[-88,-70],[-13,-53],[-48,-27],[-21,-35],[-58,-39],[21,-49],[-89,-76],[-49,-21],[46,-46],[-38,-69],[-81,-13],[-14,-86],[-44,-26],[-72,4],[-30,-40],[-48,-4],[9,-48],[-87,-21],[-24,-78],[-23,-27],[42,-35],[101,1],[21,-30],[60,-18],[29,-44],[-30,-55],[-75,-58],[-61,-2],[-28,-102],[-49,-24],[9,-49],[-53,-53],[-67,-32],[-112,-2],[-35,-27],[6,-39],[-63,-15],[-14,-53],[-52,34],[-46,-106],[-64,-2],[-102,-56],[1,-104],[-55,-60],[-5,-28],[-55,3],[-69,-39],[-54,-60],[-48,42],[-26,-13],[-25,-58],[27,-35],[-58,-6],[-17,29],[-54,-9],[26,-42],[-79,-44],[-55,10],[-44,-63],[77,-21],[-59,-99],[-118,-29],[-15,-31],[-128,-28],[-33,-47],[-10,-44],[-41,-4],[10,77],[-101,-15],[-13,-33],[-92,-53],[-19,-42],[-32,25],[-24,-46],[-31,-4],[-23,34],[-41,-43],[-60,-32],[-76,2],[11,59],[31,49],[-63,6],[-31,-45],[3,-49],[-52,-70],[-47,-11],[24,-52],[-71,-35],[-69,10],[-11,88],[-42,20],[-15,-33],[38,-37],[3,-54],[-55,-37],[-40,8],[-24,58],[-21,14],[-40,-31],[52,-44],[-49,-42],[43,-71],[-100,14],[-5,-28],[-40,-20],[-44,11],[-93,-7],[-68,-40],[-6,-29],[-79,-32],[-56,11],[-28,70],[65,38],[44,101],[57,2],[86,34],[37,31],[99,4],[25,-35],[41,16],[-6,53],[58,26],[40,-6],[21,45],[49,21],[125,159],[119,93],[144,42],[59,-19],[48,26],[-8,-82],[44,19],[75,3],[16,-33],[45,30],[-72,36],[-9,29],[58,122],[58,53],[87,64],[139,56],[16,23],[84,57],[29,-26],[53,-2],[-11,62],[17,59],[72,90],[100,61],[22,33],[66,59],[-4,49],[17,65],[16,114],[52,21],[-42,46],[3,51],[24,50],[102,90],[19,48],[-29,23],[-120,-50],[-161,-62],[-53,22],[-5,28],[-59,33],[-15,48],[-41,-21],[-1,-44],[-24,-30],[43,-95],[-53,-41],[-46,15],[-90,150],[-53,61],[-41,14],[-20,-56],[-28,-11],[-40,47],[-26,-9],[-37,35],[-9,56],[-120,-71],[-160,-74],[-10,-34],[-85,-45],[-70,40],[46,53],[-16,127],[-42,39],[7,94],[70,57],[-57,111],[-50,62],[-2,28],[-97,112],[-14,-88],[-70,-18],[-114,-50],[-106,-20],[-102,1],[-50,15],[-26,50],[5,33],[-54,23],[-36,54],[-50,43],[-72,20],[-63,70],[-47,4],[82,80],[9,66],[-40,9],[-5,51],[21,47],[-47,45],[-31,-50],[-51,19],[-9,74],[-71,25],[-10,38],[45,35],[-44,25],[-44,-10],[-18,44],[90,18],[-54,25],[-23,32],[92,10],[40,21],[-40,60],[23,59],[158,169],[23,52],[48,20],[-11,44],[26,72],[55,49],[-14,18],[58,50],[78,21],[112,-20],[32,-32],[82,-46],[76,11],[60,64],[64,31]],[[2690,20109],[74,-1],[86,-22],[-47,-64],[-51,13],[-91,-12],[-44,-34],[-9,-43],[-46,0],[-26,45],[-81,47],[-38,-2],[-28,47],[-53,31],[-84,26],[-65,4],[-100,-52],[-75,27],[-30,52],[29,80],[37,7],[62,-22],[130,-26],[115,55],[57,-5],[51,-32],[13,-54],[111,-28],[27,-24],[76,-13]],[[4516,20232],[66,2],[8,-33],[-74,-5],[0,36]],[[19220,8444],[0,-362],[0,-446],[0,-289],[0,-397],[0,-247],[-1,-433],[0,-335]],[[19219,5935],[-214,0],[-342,0],[-363,185],[-200,98],[-180,92],[-283,139],[1,54],[25,45]],[[17663,6548],[53,17],[16,39],[-11,77],[-45,9],[-10,26],[9,77],[-13,57],[26,13],[19,45],[17,74],[-10,101],[20,31],[12,49],[45,30],[31,57],[-56,66],[-35,115],[-44,68],[0,61]],[[17687,7560],[16,60],[-6,83],[-23,72],[7,54],[-16,87],[8,35],[-13,26],[-2,71],[45,20],[55,-3],[37,-57],[23,4],[29,75],[-1,357]],[[17846,8444],[298,0],[167,1],[259,0],[251,1],[8,-3],[232,0],[159,1]],[[23338,6682],[0,236],[-33,16],[-60,-20],[-28,41]],[[23217,6955],[7,445],[8,333],[-52,489]],[[23180,8222],[139,0],[271,0],[213,0],[259,-1],[344,0],[24,-50],[-5,-49],[-38,-39],[-43,-84],[177,3]],[[24521,8002],[21,-33],[-30,-16],[-13,-58],[-37,-9],[10,-54],[-35,-31],[-10,-72],[-23,-54],[26,-56],[-30,-8],[-10,-41],[-27,-13]],[[24363,7557],[16,-39],[-45,-34],[-28,-89],[-27,-106],[-39,-11],[5,-26],[-57,-88],[16,-35],[-55,-24],[10,-87],[-9,-54],[-37,2],[-2,-43],[40,-152],[-23,-96]],[[24128,6675],[-216,1],[-232,4],[-342,2]],[[16145,7115],[48,12],[28,-37],[-41,-20],[-35,45]],[[16625,6872],[36,-19],[-26,-36],[-10,55]],[[16214,10656],[-1,-359],[2,-303],[-1,-241],[-2,-324],[1,-99],[114,-127],[224,-253],[245,-286],[138,-164],[229,-277],[217,-271],[131,-166],[176,-226]],[[17663,6548],[-364,-42],[-296,-39],[-4,41],[-30,19],[-1,90],[-21,110],[-49,94],[-77,92],[-39,28],[-44,55],[-47,-11],[-41,17],[5,43],[-35,83],[-62,2],[-17,-14],[-112,64],[-15,48],[-80,71],[-86,-2],[-37,23],[-36,5],[-91,-11],[-11,33],[-37,26],[12,49],[-2,67],[-17,27],[12,70],[-19,48],[-24,3],[-31,31],[8,69],[-37,26],[-45,77],[-32,17],[-13,48],[-36,46],[-11,50],[-20,12],[-39,75],[-49,54],[-12,74],[4,66],[28,10],[10,65],[-21,57],[-67,11],[-27,25],[-55,81],[1,72],[-14,54],[-17,18],[0,115],[30,13],[13,-97],[68,-37],[-14,71],[-46,51],[5,48],[-28,20],[41,48],[-38,47],[-24,-19],[4,-122],[-95,72],[-32,16],[-8,93],[-44,92],[-56,51],[-30,60],[-78,96],[9,62],[-37,138],[17,81],[-24,124],[-71,120],[-21,12],[-48,58],[-13,78],[22,79],[47,115],[13,68],[-12,11],[25,171],[-22,119],[-31,33],[12,95]],[[15057,10657],[133,0],[371,5],[368,-7],[285,1]],[[20591,10216],[325,0],[224,0],[0,-442]],[[21140,9774],[2,-527],[0,-340],[1,-466]],[[21143,8441],[-264,3]],[[20879,8444],[-367,-3],[-181,0],[-330,1],[-184,-1],[-151,3],[-227,0],[-219,0]],[[19220,8444],[1,516],[-5,49],[3,377],[0,331],[0,499]],[[19219,10216],[219,-1],[172,1],[386,-2],[374,0],[221,2]],[[29444,10662],[3,-156],[-3,-106],[-17,-43]],[[29427,10357],[-23,8],[-122,-34],[-17,8],[-83,-6],[-43,8],[-61,-61],[-66,-19],[-78,-52]],[[28934,10209],[-20,51],[68,49],[-19,37],[17,334]],[[28980,10680],[134,-5],[329,-7],[1,-6]],[[28413,9598],[-1,11]],[[28412,9609],[1,-11]],[[28451,9685],[-26,-51]],[[28425,9634],[-21,-16],[-1,-84],[42,-66],[12,-48],[-1,-65],[23,-59],[34,-52],[30,-15],[9,-142]],[[28552,9087],[-177,4],[-17,348],[-9,210]],[[28349,9649],[47,50],[55,-14]],[[28006,9237],[1,27],[-24,37]],[[27983,9301],[22,27],[36,-46],[-35,-45]],[[26758,2980],[6,15],[46,22],[25,-40],[-25,-14],[-52,17]],[[26796,5659],[16,-193],[36,-217],[25,-101],[55,-181],[70,-173],[37,-76],[14,-55],[-18,-22],[-4,-68],[10,-72],[50,-157],[36,-160],[44,-159],[17,-99],[-2,-100],[-19,-214],[-5,-139],[-32,-25],[-26,-96],[1,-71],[-23,-46],[-69,-43],[-63,1],[-50,-10],[-25,46],[15,59],[-25,66],[-9,48],[-50,113],[-61,13],[-12,-20],[-31,105],[-8,91],[-22,59],[-36,41],[-17,-16],[-9,68],[20,46],[-3,96],[-27,-19],[7,-56],[-33,-2],[-49,122],[-33,106],[-34,64],[1,23],[28,44],[53,107],[-6,28],[-59,43],[12,-80],[-13,-47],[-22,-5],[-32,54],[18,176],[25,99],[5,66],[-21,115],[12,24],[-20,39],[-18,73],[-47,9],[-47,49],[-14,58],[-50,43],[-3,67],[-34,24],[-28,72],[-106,96],[-36,-13],[-31,11],[-25,-18],[7,-59],[-55,-6],[-79,-67],[-25,11],[-22,-31],[-30,2],[-43,-16],[-11,51],[-29,62],[-23,10],[-27,42],[-30,19],[-50,52],[-58,39],[-57,26],[-92,15],[-76,-10],[-67,-20],[-39,-2],[-61,-19]],[[25820,5788],[18,-52],[6,-58],[13,-18],[222,-17],[254,-22],[252,-25],[1,-63],[11,-29],[34,2],[9,102],[-7,68],[25,35],[70,-35],[68,-17]],[[26006,7553],[193,0],[141,6]],[[26340,7559],[-4,-27],[-56,-67],[-4,-47],[47,-41],[45,-52],[28,6],[43,-97],[8,-52],[33,-53],[11,-37],[58,-50],[25,-33],[16,-57],[41,-29],[33,-45],[5,-61],[56,-92],[24,-10],[34,-38],[-3,-31],[23,-46],[2,-96],[36,-27],[44,-119],[-10,-21],[11,-55],[30,-7],[34,-29]],[[26950,6246],[12,-11],[-80,-128],[-12,-91],[-28,-66],[1,-34],[-40,-121],[4,-48],[-11,-88]],[[25654,7552],[352,1]],[[6393,1026],[54,-54],[48,-20],[37,-29],[51,-73],[-2,-49],[24,0],[6,-43],[47,-49],[-3,-22],[-43,-58],[-42,-33],[-45,-4],[-57,-57],[-25,-70],[-21,-28],[-15,24],[-42,29],[-11,38],[9,95],[-23,111],[-26,64],[34,53],[31,82],[-19,48],[-1,40],[34,5]],[[5390,1900],[22,-1],[15,-46],[-10,-68],[-31,-39],[-45,11],[-40,37],[-8,37],[14,35],[41,37],[42,-3]],[[6054,1442],[40,-10],[26,7],[-6,-46],[-23,-12],[-55,25],[-64,0],[19,51],[63,-15]],[[6164,1371],[18,-9],[20,-49],[41,25],[26,-9],[31,-46],[31,-14],[5,-32],[-19,-30],[-89,-34],[-17,16],[-6,74],[-46,17],[-19,44],[24,47]],[[6055,1329],[31,-7],[24,-47],[-8,-20],[-36,-13],[-11,87]],[[5771,1495],[-19,-2],[-33,83],[-6,42],[36,1],[43,56],[86,-182],[-46,-18],[-40,30],[-21,-10]],[[18671,10659],[-309,-2],[-296,-1],[-176,-3],[-41,2]],[[17849,10655],[-272,1],[-367,0],[-180,2]],[[17030,10658],[0,454],[0,357],[25,84],[-12,28],[22,31],[-44,34],[-51,73],[55,155],[30,17],[28,66],[-4,39],[32,52],[15,81],[58,130],[-35,72],[-52,21],[-37,75]],[[17060,12427],[-12,46],[10,32],[-36,77],[4,36],[0,310],[-1,315],[2,236],[1,278]],[[17028,13757],[270,1]],[[17298,13758],[0,-453],[62,-100],[27,-25],[10,-44],[-16,-18],[60,-112],[55,-21],[90,-125],[20,-61],[76,-45],[10,-42],[80,-12],[-36,-164],[-11,-86],[29,-73],[-31,-14],[-18,-34],[17,-23],[-15,-61],[27,-10],[35,-45],[54,43],[41,65],[49,-45],[-7,-36],[27,-57],[0,-30],[44,-87],[34,-30],[-1,-86],[89,-41],[35,-143],[32,-24],[29,39],[84,-2],[52,39],[49,-21],[65,19],[13,-24],[65,24],[31,45],[41,26],[27,-63],[48,-47]],[[18670,11754],[1,-431],[1,-345],[-1,-319]],[[25052,10876],[-10,-84],[10,-42],[32,-58],[23,-111],[21,-52]],[[25128,10529],[-1,-260],[0,-292],[-2,-256],[0,-237],[-21,-29],[-8,-51],[35,-94],[-11,-42],[15,-36],[-6,-36],[-28,-26],[-9,-56],[-25,-46],[-66,-88],[15,-18],[-27,-64],[-8,-71],[8,-29]],[[24989,8798],[-36,-60],[20,-85],[-53,-8],[-54,-30],[-11,-45],[25,-58],[-9,-35],[-24,-2],[-102,68],[-31,-5],[-42,-77],[14,-25]],[[24686,8436],[-44,5],[-62,130],[26,49],[-25,61],[1,67],[-20,12],[-71,85],[-16,-16],[-63,86],[-31,22],[-30,45],[1,72],[43,98],[-5,50],[27,61],[-38,31],[-55,21],[-25,-41],[-33,22],[-18,145],[-91,96],[-11,31],[-74,86],[-16,47],[2,34],[-20,54],[-4,88],[24,63]],[[24058,9940],[12,6],[8,96],[61,27],[8,63],[37,50],[4,76],[-46,64],[18,75],[53,19],[55,4],[17,22],[36,5],[33,29],[7,64],[35,31],[13,89],[-6,50],[-62,48],[-24,70],[-45,55]],[[24272,10883],[156,0],[353,-7],[271,0]],[[25870,9376],[-21,-23],[16,-29],[7,-86],[-46,-6],[-58,-40],[-19,22],[-53,-13],[5,-82],[-51,-45],[-9,-42],[-38,-17],[-32,-57],[-12,-69],[-62,3],[-54,53],[-39,-39],[-5,-56],[-17,-22],[-42,20],[-12,34],[-66,-36],[-10,-47],[-41,21],[-44,38],[-58,-21],[-66,-5],[-21,-30],[-33,-4]],[[25128,10529],[27,-29],[40,-10],[43,11],[81,51]],[[25319,10552],[284,-1],[271,1],[0,-29]],[[25874,10523],[1,-396],[-1,-217],[-3,-220],[-1,-314]],[[24114,11322],[4,-67],[40,-42],[-33,-55],[8,-97],[26,-77],[27,-22],[64,-20],[22,-59]],[[24058,9940],[-16,2],[-69,102],[-101,-5],[-319,-9],[-337,-5],[-351,7]],[[22865,10032],[-6,32],[-27,33],[21,67],[-15,50],[0,85],[-13,22],[-6,100],[-43,30],[-7,72],[13,48],[-25,44],[8,31],[-38,32],[-21,54],[6,28],[-23,47],[6,61],[-16,7]],[[22679,10875],[-20,62],[-34,47],[31,68],[5,60],[19,39],[-12,49],[-19,1],[8,75],[-20,46],[40,0]],[[22677,11322],[195,0],[349,0],[185,0],[276,0],[231,0],[201,0]],[[21140,9774],[176,0],[258,-1],[180,0],[241,0],[230,0],[288,0],[246,0],[232,-1]],[[22991,9772],[28,-40],[34,-21],[34,18],[20,-30],[-23,-62],[-16,-13],[-21,-58],[50,-66],[27,-77],[59,-40],[-1,-221],[-2,-376],[0,-343]],[[23180,8443],[-216,1],[-300,0],[-264,0],[-245,-1],[-355,1],[-299,0],[-358,-3]],[[24589,8222],[-15,0]],[[24574,8222],[15,0]],[[26652,8682],[-105,-120],[-40,-17],[-61,-48],[0,-27],[-28,-24],[-16,-51],[-53,-15],[-33,-51],[-63,-32],[-30,-1],[-39,-29]],[[26184,8267],[-4,-8],[-234,6],[-179,13],[-81,-4],[-94,3],[-138,12],[-214,-3],[-203,-4],[-59,20],[4,-81],[-292,3],[-82,-2]],[[24608,8222],[11,52],[41,-21],[19,43],[-11,22],[22,76],[-4,42]],[[25870,9376],[18,19],[33,-31],[34,7],[56,-38],[25,-89],[39,-16],[59,-6],[23,-44],[29,-13],[40,33],[43,-19],[20,-28],[41,13],[30,43],[38,15],[13,-72],[34,-16],[36,-60]],[[26481,9074],[5,-70],[-17,-56],[23,-30],[14,-61],[22,-21],[34,-88],[48,-59],[42,-7]],[[23394,5208],[-23,56],[19,20],[31,70],[12,58],[-5,63],[-12,41],[17,25],[-8,58],[29,53],[18,58],[-3,28],[14,60],[-23,67],[-35,146],[-25,22],[-1,97],[-24,53],[-37,47],[0,452]],[[24128,6675],[-13,-36],[19,-36],[-6,-40],[28,-22],[-24,-27],[16,-41],[-1,-40],[36,-11],[-11,-29],[24,-28],[-68,-48],[31,-32],[-18,-61],[-23,-34],[-37,-26],[-16,-91],[-33,-50],[-1,-114],[-29,-70],[0,-52],[341,0],[173,1],[7,-4],[-33,-143],[22,-68],[23,-28],[15,-50],[3,-50],[25,-20]],[[24578,5425],[-25,-11],[-18,-36],[-48,-31],[45,-60],[26,5],[5,50],[24,21],[49,-52],[-37,-98],[-55,21],[8,-41],[-20,-66],[51,-54],[35,2],[49,-19],[55,-74],[-17,-49],[-74,-13],[-41,77],[-67,39],[-25,36],[-9,42],[-50,-23],[0,-46],[-17,-37],[-3,-40],[-32,-28],[-30,85],[-64,3],[-22,-48],[-55,-48],[-32,50],[-36,3],[-51,27],[4,99],[-70,25],[-28,92],[-32,6],[-33,-21],[-9,59],[-60,-41],[-1,-54],[75,4],[35,-34],[-30,-35],[-62,49],[-31,-2],[-41,-21],[-94,24],[-88,56],[-70,28],[-68,-4],[-73,-14],[-27,-20]],[[30271,11567],[-29,-9],[-14,34],[32,34],[11,-59]],[[29744,11132],[-33,25],[2,49],[-41,47],[-6,199],[-11,382],[-15,288]],[[29640,12122],[37,13],[18,-45],[47,69],[22,12],[-25,43],[22,41],[71,57],[-9,27],[43,42],[-14,77],[20,36],[-15,20],[23,61],[42,39],[16,123],[212,339],[52,-23],[-1,-72],[40,-28],[87,46],[40,-2],[26,34],[31,-6],[75,-66],[44,-57],[3,-498],[-6,-117],[43,-29],[60,-15],[-21,-40],[23,-50],[-13,-36],[17,-60],[37,14],[43,-35],[37,-135],[-58,-72],[-33,7],[-71,-57],[-79,-3],[-3,-30],[-50,-56],[-20,66],[-48,-13],[34,-54],[-63,-34],[1,55],[-37,10],[-19,-55],[-58,39],[-4,44],[-44,-21],[8,-44],[-22,-36],[-17,-57],[10,-15],[-38,-57],[-53,13],[-7,-25],[-63,-55],[-50,-31],[-10,24],[-50,24],[-38,-25],[-17,-40],[16,-52],[-46,-16],[-2,-42],[-26,-41],[-19,-2],[-11,-51],[-36,-67]],[[28278,8866],[14,0]],[[28292,8866],[-14,0]],[[27983,9301],[-60,57],[-34,5],[-18,31],[20,35],[-30,36],[-42,7]],[[27819,9472],[-21,75],[-86,85],[-20,5],[-24,-33],[-42,2],[-11,-46],[-63,11],[-29,27],[-43,-63],[-39,0],[-43,-56],[-64,-58],[2,228]],[[27336,9649],[258,1],[275,-1],[150,-1],[330,1]],[[28552,9087],[-40,-158],[-13,-30]],[[28499,8899],[-105,-15],[-13,-19]],[[28381,8865],[-56,27],[10,45],[-29,33],[-17,52],[-29,-8],[-40,14],[-22,77],[13,34],[39,30],[-51,60],[47,101],[-32,64],[30,83],[-53,-9],[-22,-52],[1,-63],[13,-18],[-35,-66],[1,-148],[35,-62],[1,-76],[18,-35],[-11,-35],[-33,25],[-30,44],[-57,10],[-34,24],[-26,68],[-53,-38],[-18,54],[39,68]],[[27980,9168],[25,37],[1,32]],[[29774,10424],[40,-55],[-71,-2],[6,44],[25,13]],[[29263,10980],[319,-13],[45,55],[55,28],[31,-6]],[[29713,11044],[13,-74],[42,-34],[-10,-20],[-60,-16],[4,-25],[-34,-29],[-2,-70],[60,-8],[36,-71],[-6,-56],[30,-14],[3,-51],[19,-24],[58,-21],[20,17],[69,26],[2,-52],[-87,-28],[-31,1],[-37,-35],[-45,-4],[9,75],[-26,10],[-25,-49],[-33,-7],[0,-31],[-52,-18]],[[29630,10436],[-3,72],[-18,6]],[[29609,10514],[-8,16]],[[29601,10530],[-28,31],[-15,50],[0,55],[-114,-4]],[[28980,10680],[-5,16],[66,292]],[[29041,10988],[222,-8]],[[24809,13366],[38,26],[27,-5],[-61,-67],[-63,-26],[-3,-27],[-59,-28],[-15,47],[136,80]],[[25665,12323],[18,-15],[4,-47],[-36,-17],[14,79]],[[25319,10552],[57,59],[37,99],[35,61],[29,100],[12,106],[-5,119],[-8,42],[-39,103],[-39,133],[30,88],[-23,107],[23,28],[44,100],[13,98],[-3,61],[44,28],[2,61],[37,28],[34,-9],[16,45],[37,34],[13,-37],[-23,-75],[6,-48],[28,-8],[36,81],[6,150],[45,38],[48,2],[-24,92],[58,81],[38,17],[85,-61],[68,-8],[29,-57],[55,-8],[28,-30],[57,-29],[28,2],[20,-30],[42,-118],[-35,21],[-12,-53],[33,-31],[13,-74],[-11,-47],[-5,-119],[-59,-50],[-10,-75],[-26,-28],[-41,-2],[-24,-40],[2,-100],[65,-37],[113,170],[59,19],[35,24],[49,-36],[29,-70],[9,-101],[17,-73],[4,-94],[30,-110],[-11,-23],[-4,-73],[-15,-68],[-43,-22],[-6,58],[-26,-15],[-21,-58],[-4,-56],[-48,-35],[-18,-35],[-1,-67],[-15,-36],[-38,-36],[-35,-85]],[[26245,10540],[-249,-12],[-122,-5]],[[24333,12680],[25,18],[82,30],[49,54],[49,16],[64,3],[52,28],[29,36],[40,5],[30,47],[86,64],[43,55],[65,39],[104,7],[24,-15],[-93,-63],[-43,-39],[-43,-85],[-21,-20],[-11,-63],[13,-19],[53,63],[94,-9],[74,-43],[67,-128],[35,-16],[67,20],[39,-42],[52,27],[27,-16],[25,28],[98,65],[71,8],[109,-5],[62,33],[84,7],[-21,-32],[-8,-76],[11,-20],[59,-15],[47,17],[21,-29],[36,36],[85,1],[-9,-37],[5,-106],[15,-39],[47,-41],[54,46],[34,-6],[19,-71],[-75,2],[-27,15],[-63,5],[-73,-21],[-76,54],[-25,-97],[-71,76],[-91,38],[-51,0],[-39,-55],[-40,5],[-32,-21],[-74,14],[-35,-25],[-11,-52],[-41,-16],[-37,-61],[-19,30],[44,58],[-62,20],[-15,-61],[-64,-1],[-28,-26],[-80,-172],[-41,-66],[6,-12]],[[25109,12029],[-39,36],[23,72],[-61,14],[26,105],[-10,45],[-50,38],[-27,-5],[-2,61],[-87,23],[-24,17],[-30,-11],[-44,12],[-87,55],[-282,87],[-27,73],[-55,29]],[[22677,11322],[0,425],[0,371],[-10,27],[-53,23],[-48,87],[56,62],[20,35],[4,49]],[[22646,12401],[3,65],[-13,109],[-37,66],[-17,83],[6,102],[-12,32],[-9,275],[-55,158],[-26,100],[9,48],[-13,117],[17,63],[-10,18],[-25,121]],[[22464,13758],[226,0],[343,-1],[0,171],[54,-7],[36,-33],[39,-182],[-2,-47],[29,-26],[88,-9],[6,-20],[110,-11],[13,-50],[90,13],[33,36],[100,-1],[70,-37],[20,-46],[41,5],[38,-101],[24,11],[-2,44],[34,9],[45,-19],[-2,-25],[39,-26],[41,-3],[1,-37],[78,-30],[49,16],[75,60],[38,9],[21,-63],[106,-3],[67,9],[29,-12],[42,-43],[34,16],[44,-25],[-106,-60],[-155,-57],[-54,-35],[-119,-114],[-85,-106],[-169,-150],[22,-36]],[[23895,12742],[-34,15],[-20,-40],[-22,7],[-1,-262],[-18,-27],[-95,-52],[-21,-58],[-24,-21],[-4,-63],[32,-4],[33,-55],[-30,-67],[3,-81],[-12,-12],[11,-63],[-16,-83],[74,-81],[53,-5],[36,-52],[44,-17],[35,-30],[14,-59],[81,-76],[39,-12],[53,-100],[-6,-71],[14,-51]],[[24363,7557],[240,-1],[339,1]],[[24888,5508],[-16,-17],[-39,12],[-41,-4],[-31,20],[-43,-4],[-111,-58],[-29,-32]],[[23180,8222],[0,221]],[[22991,9772],[-31,27],[6,29],[-19,45],[-39,39],[-43,120]],[[24608,8222],[-19,0]],[[24574,8222],[2,-70],[-22,-14],[5,-80],[-38,-56]],[[17298,13758],[231,-1],[416,-1],[187,1],[414,-1],[365,1],[323,0],[427,0],[381,0],[323,0],[227,0]],[[20592,13757],[1,-455],[0,-278],[0,-369],[0,-250]],[[20593,12405],[1,-419],[-5,-1]],[[20589,11985],[-279,2],[-326,-3],[-239,2],[-312,1],[-229,2],[-300,-4],[-139,-2],[-96,4],[1,-233]],[[20591,10216],[0,391],[0,494]],[[20591,11101],[252,0],[414,-2],[273,1],[318,0],[267,0],[9,-22],[93,-56],[49,-23],[29,43],[43,-11],[104,11],[48,-42],[41,-5],[81,-48],[-6,-20],[57,-55],[16,3]],[[16214,10656],[357,-2],[294,3],[165,1]],[[17849,10655],[0,-222],[-1,-319],[0,-343],[-1,-220],[-1,-443],[1,-299],[-1,-365]],[[29525,11992],[27,90],[33,38],[41,-25],[14,27]],[[29744,11132],[-31,-88]],[[29263,10980],[-23,36],[2,63],[25,27],[-4,60],[23,191],[19,55],[33,45],[18,84],[23,38],[-9,85],[10,21],[60,17],[59,57],[10,73],[-18,41],[37,74],[-3,45]],[[28649,10374],[108,-82],[109,-78],[-7,-48],[-26,-79]],[[28833,10087],[-43,-28],[-22,-81],[72,-24],[6,-49],[-15,-78],[-18,-159],[-57,-130],[-30,-49],[-55,-51],[-49,-112],[-20,-23],[-29,0],[23,97],[-80,37],[-51,44],[-47,53],[-5,64]],[[28412,9609],[13,25]],[[28451,9685],[23,21],[50,15],[5,33],[87,75],[12,38],[-78,90],[-4,56],[-34,15],[6,89],[32,42],[-21,52],[29,22],[40,62],[12,43],[39,36]],[[19911,6135],[-245,-1],[-216,0],[0,-199],[-231,0]],[[20879,8444],[0,-221]],[[20879,8223],[-11,0],[0,-389],[0,-342],[0,-375],[-6,-444],[0,-443],[-181,0],[-222,0],[-246,0],[-327,0],[-4,-59],[29,-36]],[[29020,11991],[-11,-73],[13,-18],[-15,-83],[25,-62],[-9,-47],[6,-43],[-22,-38],[-13,-63],[24,-121],[-21,-61],[34,-5],[15,-43],[-8,-307],[3,-39]],[[28934,10209],[-16,-51],[86,37],[47,-22],[24,27],[101,0],[52,14],[63,60],[26,-40],[27,5],[18,-28],[49,40],[12,-13],[-143,-82],[-223,-104],[-31,2],[-66,-23],[-59,3],[-43,-20],[-30,35],[5,38]],[[28649,10374],[-18,29],[-35,6],[-27,31],[-16,49],[-3,59],[-16,41],[-41,12],[-27,57],[-270,-1],[-408,0],[-286,0],[-244,1],[0,120]],[[27258,10778],[91,70],[22,27],[55,28],[28,60],[53,42],[-21,76],[-22,13],[-16,123],[120,42],[40,8],[140,-3],[60,-14],[50,-41],[51,14],[76,5],[44,-7],[70,32],[19,31],[60,48],[31,-4],[26,27],[-7,102],[28,41],[-2,26],[-37,18],[-27,46],[15,44],[41,36],[69,39],[40,65],[71,84],[73,72],[74,51],[40,14],[39,-7],[147,-3],[221,8]],[[28358,7647],[60,32],[3,-17],[-63,-15]],[[28327,8245],[-9,-30],[-28,-18],[22,-33],[3,-69],[-44,-32],[-93,-27],[-13,-24],[-32,-8],[-41,27],[14,-58],[75,21],[10,-18],[51,22],[32,0],[23,-42],[21,35],[32,-18],[16,-55],[-1,-82],[-46,-24],[-31,-66],[-37,-42],[-127,26],[38,-56],[-36,-85],[-55,-46],[10,-20],[35,31],[37,8],[61,-30],[-33,-37],[-34,-77],[-26,14],[-113,-23],[-49,-25],[-103,-91],[-43,-57],[-24,-48],[-33,-111],[-19,-11],[-44,12],[-57,-6],[-43,-22]],[[27593,7050],[-194,265],[-117,157],[-308,7],[4,51],[-42,76],[-30,19],[-338,22],[-51,-10],[-177,-78]],[[26006,7553],[9,105],[53,10],[21,24],[0,46],[38,50],[30,19],[76,1],[50,41],[20,31],[45,28],[23,-7],[57,95],[42,34],[23,-44],[38,52],[33,23],[39,7],[32,-13],[34,80],[31,25],[27,49],[5,53]],[[26732,8262],[231,-13],[149,-7],[215,-1],[275,0],[208,2],[229,-1],[30,3],[258,0]],[[20592,13757],[185,0],[318,0],[299,0],[333,0],[287,1],[252,0],[198,0]],[[22646,12401],[-335,0],[-173,0],[-231,2],[-251,1],[-343,0],[-412,1],[-308,0]],[[26245,10540],[106,-61],[36,-36],[22,15],[37,-14],[28,-39],[38,-21],[62,24],[66,36],[74,-13],[83,82],[118,80],[31,7],[104,48]],[[27050,10648],[0,-323],[0,-270]],[[27050,10055],[-40,-28],[18,-41],[0,-73],[-29,-72],[-9,-81],[-35,-97],[-4,-58],[-39,-31],[-55,-73],[-34,-18],[-30,28],[-61,-60],[-21,-43],[-3,-72],[-34,-62],[-12,50],[-28,17],[-50,-102],[8,-89],[-28,-7],[-9,-57],[-57,-20],[-17,8]],[[23217,6955],[-80,52],[-15,-6],[-82,87],[-28,10],[-17,-37],[-66,2],[-8,23],[-73,-43],[-31,12],[-57,-11],[-5,-30],[-30,0],[-18,-37],[-22,40],[-69,60],[-5,-28],[-48,2],[-15,47],[-69,-98],[2,48],[-12,31],[-45,-43],[-49,35],[-33,41],[-44,-59],[-37,11],[6,47],[-38,6],[-23,49],[-54,19],[-33,-41],[-25,38],[-52,-6],[-116,35],[-20,83],[-37,-11],[-51,17],[-32,-15],[-52,74],[-31,5],[0,469],[0,390],[-298,-1],[-320,1],[-206,0]],[[15057,10657],[-39,52],[-15,60],[-7,84],[12,60],[-7,38],[-27,33],[-10,46],[26,71],[6,51],[26,104],[29,92],[18,111],[13,131],[18,245],[-3,77],[25,139],[-1,89],[11,140],[-8,108],[10,73],[21,38],[85,45]],[[15240,12544],[32,-34],[41,-17],[45,18],[58,-45],[25,-54],[14,-135],[24,-17],[117,-31],[41,16],[79,54],[77,9],[123,-35],[63,11],[60,33],[36,-21],[81,12],[67,43],[81,15],[13,21],[100,16],[36,-4],[38,30],[237,0],[332,-2]],[[27050,10648],[126,74],[82,56]],[[27336,9649],[-286,0],[0,406]],[[29630,10436],[-58,9],[37,69]],[[29601,10530],[-34,8],[-16,-29],[-3,-84],[-18,-45],[-103,-23]],[[27593,7050],[-47,-23],[-62,-71],[-40,-69],[-17,-47],[-11,-90],[-39,-37],[-9,-37],[-33,-2],[-26,-43],[-41,-44],[-39,-21],[-5,-33],[-29,-30],[-59,-27],[-35,-34],[-38,8],[12,-47],[-10,-31],[-53,-32],[-17,-39],[-34,-22],[-11,-33]],[[20591,11101],[-1,378],[-1,506]],[[26184,8267],[216,-3],[262,0],[70,-2]],[[23394,5208],[-44,-4],[-36,-16],[-127,-79],[13,46],[-53,-20],[12,87],[-33,15],[-16,-38],[-36,-5],[6,-66],[20,-6],[5,-84],[-57,-59],[20,-12],[-90,-110],[-126,-103],[-47,-26],[-13,20],[-45,-29],[-29,26],[-47,-32],[19,-58],[-74,-47],[-33,13],[-2,-63],[-37,-44],[-28,27],[-48,-43],[45,-29],[-38,-88],[-17,23],[-35,-17],[2,-42],[32,-20],[-19,-56],[-23,-107],[-30,14],[-26,-33],[19,-25],[33,12],[-16,-114],[-21,-4],[-2,-66],[25,-37],[17,-137],[22,-43],[-4,-37],[20,-80],[20,-4],[14,-54],[-35,-2],[-25,-16],[-2,-33],[-41,20],[-35,60],[-65,20],[-42,-11],[-57,14],[-60,66],[-33,14],[-23,-8],[-42,60],[-79,24],[-15,49],[-12,83],[-16,53],[-49,79],[6,68],[-22,72],[7,65],[-9,35],[-25,35],[-28,5],[-30,53],[-17,11],[-5,44],[-27,43],[-25,66],[-34,20],[-24,42],[-11,65],[-45,102],[-2,35],[-40,90],[-6,69],[-28,33],[-6,32],[-58,54],[-14,40],[-55,35],[-37,87],[-22,21],[-65,-6],[-72,19],[-39,-8],[-18,23],[-43,11],[-13,-46],[-28,8],[-52,-20],[-4,-28],[-32,-68],[-16,-131],[-64,-75],[-4,-32],[-46,-1],[-40,27],[-36,49],[-45,17],[-31,38],[-55,19],[-39,41],[-23,44],[-21,3],[-46,53],[-16,58],[-31,68],[-8,56],[6,57],[-21,54],[-27,40],[-11,79],[-24,40],[-57,58],[-55,28],[-44,60],[-13,41],[-47,37],[-49,88],[-69,45],[-48,118],[-41,23]],[[18671,10659],[0,-445],[150,-1],[398,3]],[[29020,11991],[136,3],[147,-6],[222,4]],[[28292,8866],[-14,0]],[[28499,8899],[-30,-68],[-28,-5],[-17,-28],[-27,-86],[5,-16],[-47,-117],[-10,-47],[-29,-37],[-17,2],[-15,61],[31,162],[30,62],[31,44],[5,39]],[[27980,9168],[-32,-20],[-21,-62],[23,-52],[63,19],[-5,-28],[19,-43],[33,-23],[62,-6],[27,-54],[77,-61],[-20,-34],[2,-55],[-30,-47],[30,-9],[15,-78],[-39,0],[-3,-100],[35,-33],[-43,-51],[-10,25],[-42,41],[-9,45],[-29,-13],[74,-106],[44,3],[63,-22],[28,6],[35,-165]],[[26652,8682],[11,-78],[46,-38],[23,-33],[32,3],[55,58],[37,-46],[31,19],[46,8],[44,44],[22,0],[42,35],[21,-23],[48,38],[12,39],[-11,42],[37,82],[44,52],[29,88],[30,36],[27,70],[11,71],[31,-18],[16,-42],[46,-20],[27,36],[38,113],[22,45],[34,-38],[22,54],[52,35],[8,30],[46,60],[-4,40],[21,42],[-2,50],[143,-148],[30,84]],[[15522,13442],[-27,3],[16,-77],[50,-38],[-15,-53],[-48,51],[-1,54],[-44,34],[27,56],[42,-30]],[[15534,13098],[20,-57],[-34,-16],[14,73]],[[15445,13581],[8,-17],[-28,-64],[-46,18],[-34,31],[-4,41],[36,0],[35,41],[49,-23],[-16,-27]],[[15240,12544],[-49,19],[-51,-25],[-42,36],[10,60],[37,33],[-36,76],[-20,17],[-11,70],[24,-6],[16,39],[-51,50],[-16,86],[-23,30],[-10,85],[-21,88],[-53,63],[-13,34],[-9,97],[13,65],[17,23],[59,-43],[39,-10],[52,-38],[95,-4],[31,-14],[94,-9],[23,22],[79,-52],[29,2],[37,-82],[33,6],[7,-61],[-8,-41],[7,-62],[-22,-85],[36,-23],[32,55],[-29,119],[11,66],[44,98],[-37,42],[-12,89],[-47,46],[43,75],[-21,25],[-10,53],[-30,-1],[-38,50],[7,52],[277,-3],[480,1],[320,1],[175,0],[320,-1]],[[23895,12742],[53,-7],[85,30],[78,47],[36,-1],[71,42],[23,-26],[-36,-63],[-6,-76],[42,27],[92,-35]],[[25109,12029],[-11,-53],[-52,-11],[-2,-27],[-43,-75],[-6,-81],[66,46],[43,87],[56,29],[39,78],[7,38],[56,25],[-4,-59],[-39,-53],[-4,-42],[-27,-31],[-45,-112],[-21,-102],[7,-63],[-35,-33],[-25,-99],[9,-89],[-24,-52],[-33,-138],[13,-78],[-6,-33],[17,-73],[16,-22],[-13,-63],[4,-67]],[[30915,246],[147,-15],[64,-39],[15,-60],[-42,-35],[-18,-59],[-50,-16],[-38,-22],[-45,21],[-18,-17],[-21,23],[-34,-13],[-51,20],[-44,-28],[-36,14],[-42,-5],[16,112],[-30,61],[29,27],[5,40],[51,-7],[142,-2]]]} -------------------------------------------------------------------------------- /source/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/mapper/b9bb8c751d8e07422eb564fcace8cbd83150f7b6/source/images/background.png -------------------------------------------------------------------------------- /source/images/share-embed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/mapper/b9bb8c751d8e07422eb564fcace8cbd83150f7b6/source/images/share-embed.png -------------------------------------------------------------------------------- /source/images/share-png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/mapper/b9bb8c751d8e07422eb564fcace8cbd83150f7b6/source/images/share-png.png -------------------------------------------------------------------------------- /source/images/share-svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/mapper/b9bb8c751d8e07422eb564fcace8cbd83150f7b6/source/images/share-svg.png -------------------------------------------------------------------------------- /source/images/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/mapper/b9bb8c751d8e07422eb564fcace8cbd83150f7b6/source/images/texture.png -------------------------------------------------------------------------------- /source/index.html.erb: -------------------------------------------------------------------------------- 1 | --- 2 | title: Mapper 3 | --- 4 |
5 | <%= partial 'partials/m-map-preview' %> 6 |
7 | 8 |
9 | 13 | <%= partial 'partials/m-editor-settings' %> 14 | <%= partial 'partials/m-editor-style' %> 15 |
16 | 17 | <%= partial 'partials/m-editor-data' %> 18 | 19 | <%= javascript_include_tag 'renderer' %> 20 | <%= javascript_include_tag 'application' %> -------------------------------------------------------------------------------- /source/javascripts/application.js: -------------------------------------------------------------------------------- 1 | //= require "vendor/jquery" 2 | //= require "vendor/underscore" 3 | //= require "vendor/backbone" 4 | //= require "vendor/backbone.epoxy" 5 | 6 | //= require "vendor/canvg/rgbcolor" 7 | //= require "vendor/canvg/StackBlur" 8 | //= require "vendor/canvg/canvg" 9 | 10 | //= require "mapper/main" 11 | //= require "mapper/models/settings" 12 | //= require "mapper/models/styles" 13 | //= require "mapper/models/data" 14 | 15 | //= require "mapper/views/map-preview" 16 | //= require "mapper/views/editor-data" 17 | //= require "mapper/views/editor-main" 18 | //= require "mapper/views/editor-settings" 19 | //= require "mapper/views/editor-style-base" 20 | //= require "mapper/views/editor-style-list" 21 | 22 | //= require "mapper/interactive" 23 | 24 | $(function() { Mapper.init(); }); 25 | -------------------------------------------------------------------------------- /source/javascripts/mapper/interactive.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var $tooltip = $('
').hide().appendTo('body'); 3 | var content = null; 4 | 5 | $('.map-view').on('mousemove touchdown', function(evt) { 6 | var data = evt.target.getAttributeNS(null, 'data-tooltip'); 7 | 8 | if (data && data !== content) { 9 | $tooltip.html(data).show(); 10 | content = data; 11 | } else if (content && !data) { 12 | $tooltip.hide(); 13 | content = null; 14 | } 15 | 16 | if (content) { 17 | var w = $tooltip.outerWidth(); 18 | var h = $tooltip.outerHeight(); 19 | $tooltip.css({ 20 | left: (evt.pageX-w/2) +'px', 21 | top: (evt.pageY-h-20)+'px' 22 | }); 23 | } 24 | }); 25 | }()); -------------------------------------------------------------------------------- /source/javascripts/mapper/main.js: -------------------------------------------------------------------------------- 1 | var Mapper = { 2 | models: {}, 3 | views: {}, 4 | 5 | init: function() { 6 | this.settings = new this.models.Settings(); 7 | this.data = new this.models.Data(); 8 | this.fills = new this.models.Styles(); 9 | this.strokes = new this.models.Styles(); 10 | 11 | var editorMain = new this.views.EditorMainView(); 12 | 13 | var editorSettings = new this.views.MapSettingsView({ 14 | model: this.settings 15 | }); 16 | 17 | var editorBaseView = new this.views.EditorStyleBaseView({ 18 | model: this.settings 19 | }); 20 | 21 | var editorFillView = new this.views.EditorStyleListView({ 22 | el: '#editor-style-fill', 23 | collection: this.fills, 24 | model: this.settings, 25 | type: 'fill' 26 | }); 27 | 28 | var editorStrokeView = new this.views.EditorStyleListView({ 29 | el: '#editor-style-stroke', 30 | collection: this.strokes, 31 | model: this.settings, 32 | type: 'stroke' 33 | }); 34 | 35 | var editorData = new this.views.EditorDataView({ 36 | collection: this.data, 37 | model: this.settings 38 | }); 39 | 40 | this.mapPreview = new this.views.MapRenderView({ 41 | settings: this.settings, 42 | fills: this.fills, 43 | strokes: this.strokes, 44 | data: this.data 45 | }); 46 | 47 | this.fills.reset([ 48 | {value: 50, color: '#6d98a8', label: 'Reads Vox'}, 49 | {value: 100, color: '#fa4b2a', label: 'Reads Verge'} 50 | ]); 51 | 52 | window.onbeforeunload = function() { 53 | //return "You are about to exit this layout."; 54 | }; 55 | }, 56 | 57 | getRenderConfig: function(opts) { 58 | var config = this.settings.toJSON(); 59 | config.fills = this.fills.toJSON(); 60 | config.strokes = this.strokes.toJSON(); 61 | if (opts && opts.rows) config.rows = this.data.toJSON(); 62 | return config; 63 | } 64 | }; -------------------------------------------------------------------------------- /source/javascripts/mapper/models/data.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // DataFormatter: 4 | // This guy knows how all the data works together. 5 | // A data reader is pre-configured with the all fields its going to work with, 6 | // then presented with a geography, it reads out its data configuration... 7 | // Kind of an IOC on object-orientation, where the process is specialized rather than the object. 8 | var DataFormatter = { 9 | val: function(value) { 10 | switch (this.dataType) { 11 | case 'number': return value === '' ? null : Number(value); 12 | case 'string': return String(value); 13 | } 14 | } 15 | }; 16 | 17 | // Individual Datum model: 18 | // will be extended with shape data, and any CSV imports: 19 | // provides an object-oriented API for accessing its own style data. 20 | var Datum = Backbone.Model.extend({ 21 | defaults: { 22 | id: '', 23 | value: 0 24 | } 25 | }); 26 | 27 | // Data collection: 28 | // manages a collection of geographies, 29 | // and manages the definition of their field data types. 30 | Mapper.models.Data = Backbone.Collection.extend({ 31 | model: Datum, 32 | comparator: 'id', 33 | _sort: {}, 34 | 35 | // Custom method for column-type aware sorting: 36 | sort: function() { 37 | var self = this; 38 | DataFormatter.dataType = Mapper.settings.columnType(this.comparator); 39 | 40 | this.models.sort(function(a, b) { 41 | var va = DataFormatter.val(a.get(self.comparator)); 42 | var vb = DataFormatter.val(b.get(self.comparator)); 43 | var diff; 44 | 45 | // Primary sort on column value: 46 | if (DataFormatter.dataType === 'string') { 47 | diff = va.localeCompare(vb); 48 | } else { 49 | diff = va - vb; 50 | } 51 | 52 | // Secondary sort on id: 53 | if (diff === 0) { 54 | return a.id.localeCompare(b.id); 55 | } 56 | 57 | return diff; 58 | }); 59 | 60 | this.trigger('sort'); 61 | }, 62 | 63 | loadCSV: function(file) { 64 | var reader = new FileReader(); 65 | 66 | reader.onload = _.bind(function() { 67 | this.resetData(d3.csv.parse(reader.result)); 68 | }, this); 69 | 70 | reader.readAsText(file); 71 | }, 72 | 73 | resetData: function(data) { 74 | this._datatypes = {}; 75 | this.reset(data, {silent: true}); 76 | Mapper.settings.set('columns', this.getColumns()); 77 | this.trigger('reset change'); 78 | }, 79 | 80 | // Gets an object with all columns and their data types. 81 | // Returns as {col1:'string', col2:'number'} 82 | getColumns: function() { 83 | // Function used to detect known data types: 84 | // We're deliberately returning null if we can't make a good assessment of a value. 85 | function detectType(s) { 86 | var key; 87 | 88 | // Check for un-determinable string values: 89 | if (typeof s === 'string') { 90 | if (s === '' || s.toLowerCase() === 'null') return null; 91 | } 92 | 93 | // Try to cast it to a number: 94 | if ((key = +s) == key) return 'number'; 95 | 96 | // Check for string with length: 97 | if (String(s).length) return 'string'; 98 | 99 | // Give up: 100 | return null; 101 | } 102 | 103 | // Return empty if there is no data: 104 | if (!this.length) return {}; 105 | 106 | // Clone first row for the column set: 107 | var columns = this.at(0).toJSON(); 108 | 109 | // Loop through all columns, and detect a datatype for each. 110 | // We'll keep looking through rows until we find an assessable value for each column. 111 | // Columns with no assessable values will be left as strings. 112 | for (var column in columns) { 113 | if (columns.hasOwnProperty(column)) { 114 | var type; 115 | 116 | for (var i = 0; i < this.length; i++) { 117 | type = detectType(this.at(i).attributes[column]); 118 | if (type) break; 119 | } 120 | 121 | columns[column] = type || 'string'; 122 | } 123 | } 124 | 125 | return columns; 126 | } 127 | }); 128 | 129 | }()); -------------------------------------------------------------------------------- /source/javascripts/mapper/models/settings.js: -------------------------------------------------------------------------------- 1 | Mapper.models.Settings = Backbone.Epoxy.Model.extend({ 2 | defaults: { 3 | el: 'mapper-'+Date.now(), 4 | columns: {id: 'string', value: 'number'}, 5 | //csv: 'data/states.csv', 6 | background_color: '#eeeeee', 7 | fill_color: '#dddddd', 8 | fill_column: 'value', 9 | font_color: 'black', 10 | heat_clamp: true, 11 | heat_scale: false, 12 | height: 500, 13 | theme: 'light', 14 | type: 'world', 15 | tooltip: '<%= name %>: <%= value %>', 16 | stroke_color: 'rgba(255,255,255,0.25)', 17 | stroke_column: 'value', 18 | stroke_size: 1, 19 | header: 'My Awesome Map', 20 | header_font: '700 35px "Roboto", Helvetica', 21 | subheader: 'Subheading', 22 | subheader_font: '15px "Roboto", Helvetica', 23 | legend_font: 'bold 14px "Roboto", Helvetica', 24 | width: 960 25 | }, 26 | 27 | themes: [ 28 | { 29 | theme: 'light', 30 | background_color: '#e9e7e8', 31 | font_color: 'black' 32 | }, 33 | { 34 | theme: 'dark', 35 | background_color: '#63676a', 36 | font_color: 'white' 37 | } 38 | ], 39 | 40 | initialize: function() { 41 | this.listenTo(this, 'change:theme', this.setTheme); 42 | this.setTheme(); 43 | }, 44 | 45 | setTheme: function() { 46 | // Finds selected theme definition, and sets its attributes to the model: 47 | this.set(_.findWhere(this.themes, {theme: this.get('theme')}) || {}); 48 | }, 49 | 50 | computeds: { 51 | // Computed attributes are virtualized model properties provided by Epoxy. 52 | // Specific data formats can be constructed and bound to without formally being stored on the model. 53 | columnNames: function() { 54 | return _.keys(this.get('columns')); 55 | } 56 | }, 57 | 58 | // Gets/Sets column types: 59 | // Will trigger a "change:columns" when a type is set. 60 | columnType: function(column, type) { 61 | if (type) this.modifyObject('columns', column, type); 62 | return this.get('columns')[column]; 63 | } 64 | }); -------------------------------------------------------------------------------- /source/javascripts/mapper/models/styles.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var Style = Backbone.Model.extend({ 4 | defaults: { 5 | color: '#000000', 6 | inLegend: true, 7 | label: 'New legend item', 8 | operator: 'lte', 9 | size: 3, 10 | type: 'fill', 11 | value: 0 12 | } 13 | }); 14 | 15 | Mapper.models.Styles = Backbone.Collection.extend({ 16 | model: Style, 17 | 18 | // Shifts an item order by the specified offset: 19 | shiftItem: function(model, dir) { 20 | var at = this.indexOf(model); 21 | if (at + dir >= 0 && at + dir < this.length) { 22 | this.models.splice(at, 1); 23 | this.models.splice(at+dir, 0, model); 24 | this.trigger('sort'); 25 | } 26 | } 27 | }); 28 | 29 | }()); -------------------------------------------------------------------------------- /source/javascripts/mapper/render.js: -------------------------------------------------------------------------------- 1 | function MapRenderer(opts) { 2 | if (opts) this.init(opts); 3 | } 4 | 5 | (function() { 6 | 7 | MapRenderer.prototype = { 8 | brand: '', // << SVG path data for branding logo, if desired. 9 | options: { 10 | background_color: '#eee', 11 | columns: null, 12 | fill_color: '#ddd', 13 | stroke_color: '#fff', 14 | stroke_size: 1, 15 | type: null 16 | }, 17 | 18 | // Parses out a number, or returns null for empty values: 19 | // This is designed to distinguish between 0 and empty values. 20 | parseNumber: function(d) { 21 | return d ? +d : null; 22 | }, 23 | 24 | // Converts a value into a string: 25 | parseString: function(d) { 26 | return String(d); 27 | }, 28 | 29 | // Initializes the map with graphics and data: 30 | init: function(opts) { 31 | var self = this; 32 | var jsonLoaded = false; 33 | var csvLoaded = false; 34 | function done() { 35 | if (jsonLoaded && csvLoaded) { 36 | self.options = opts; 37 | self.render(); 38 | } 39 | } 40 | 41 | // Create shape layers: 42 | if (!this.el) { 43 | this.el = {}; 44 | var svg = this.el.svg = d3.select('#'+opts.el) 45 | .append('svg') 46 | .attr('width', '100%'); 47 | 48 | this.el.bg = svg.append('rect'); 49 | this.el.map = svg.append('g'); 50 | this.el.legend = svg.append('g'); 51 | this.el.header = svg.append('text'); 52 | this.el.brand = svg.append('path'); 53 | } 54 | 55 | this.loadJSON(opts, function() { 56 | jsonLoaded = true; 57 | done(); 58 | }); 59 | 60 | this.loadCSV(opts, function() { 61 | csvLoaded = true; 62 | done(); 63 | }); 64 | }, 65 | 66 | // Loads CSV data rows based on map options: 67 | loadCSV: function(opts, done) { 68 | if (opts.rows) return done(); 69 | 70 | // CSV needs to load: 71 | d3.csv(opts.csv, function(error, rows) { 72 | opts.rows = rows; 73 | done(); 74 | }); 75 | }, 76 | 77 | loadJSON: function(opts, done) { 78 | if (opts.type === this.options.type) return done(); 79 | var projection, featureset; 80 | var self = this; 81 | 82 | // Projections for future consideration... 83 | // times, wagner6, naturalEarth, robinson 84 | switch (opts.type) { 85 | case 'world': 86 | projection = d3.geo.times(); 87 | featureset = 'countries'; 88 | break; 89 | case 'us-county': 90 | projection = d3.geo.albersUsa(); 91 | featureset = 'counties'; 92 | break; 93 | case 'us-state': 94 | projection = d3.geo.albersUsa(); 95 | featureset = 'states'; 96 | break; 97 | } 98 | 99 | // Load shapefile and CSV data 100 | d3.json('data/'+opts.type+'.json', function(error, data) { 101 | self.geodata = topojson.feature(data, data.objects[featureset]).features; 102 | self.path = d3.geo.path().projection(projection); 103 | 104 | // Map array of geo properties: 105 | // Give all countries an empty value, and exclude unnamed geographies. 106 | var data = []; 107 | for (var i = 0; i < self.geodata.length; i++) { 108 | var props = self.geodata[i].properties; 109 | if (props.name) data.push(props); 110 | } 111 | 112 | done(); 113 | 114 | // Populate map data as rows: 115 | if (typeof self.onData === 'function') self.onData(data); 116 | }); 117 | }, 118 | 119 | getRowValue: function(styler, row) { 120 | var opts = this.options; 121 | styler = styler.split('_'); 122 | var styleGroup = styler[0]; 123 | var columnName = opts[styleGroup+'_column']; 124 | var isNumeric = (opts.columns[columnName] === 'number'); 125 | var parser = isNumeric ? this.parseNumber : String; 126 | return parser(row[columnName]); 127 | }, 128 | 129 | // Gets the style for a value: 130 | // field is defined as "fill_color". 131 | getStyle: function(styler, row) { 132 | var opts = this.options; 133 | styler = styler.split('_'); 134 | var styleGroup = styler[0]; 135 | var styleAttr = styler[1]; 136 | var styles = opts[styleGroup+'s']; 137 | 138 | // Return early with default style if there are no options: 139 | if (!styles.length || !row) return null; 140 | 141 | var columnName = opts[styleGroup+'_column']; 142 | var isNumeric = (opts.columns[columnName] === 'number'); 143 | var value = row[columnName]; 144 | 145 | // Parse numeric column, and return default style for null values: 146 | if (isNumeric) { 147 | value = this.parseNumber(value); 148 | if (value === null) return null; 149 | } else { 150 | value = String(value); 151 | } 152 | 153 | for (var i = 0; i < styles.length; i++) { 154 | var style = styles[i]; 155 | var op = style.operator; 156 | var delta = isNumeric ? 157 | value - this.parseNumber(style.value) : 158 | value.localeCompare(String(style.value)); 159 | 160 | if ( 161 | (op === 'lt' && delta < 0) || 162 | (op === 'lte' && delta <= 0) || 163 | (op === 'eq' && delta === 0) || 164 | (op === 'gte' && delta >= 0) || 165 | (op === 'gt' && delta > 0) 166 | ) return style[styleAttr]; 167 | } 168 | 169 | return null; 170 | }, 171 | 172 | // Renders the map with new data: 173 | render: function() { 174 | var opts = this.options; 175 | 176 | this.heat = d3.scale.linear() 177 | .domain(opts.fills.map(function(d) { return +d.value; })) 178 | .range(opts.fills.map(function(d) { return d3.rgb(d.color); })) 179 | .clamp(opts.heat_clamp); 180 | 181 | // Render data, title, and all geographies: 182 | this._y = 20; 183 | renderData(this); 184 | renderHeaders(this); 185 | renderGeography(this); 186 | 187 | // Render legend based on map type: 188 | //opts.heat_scale ? renderHeatLegend(this) : renderCohortLegend(this); 189 | renderCohortLegend(this) 190 | 191 | // Render frame bounds and brand watermark: 192 | renderFrame(this); 193 | renderBrand(this); 194 | } 195 | }; 196 | 197 | // Render Data 198 | // 199 | // Pre-renders map data configuration for drawing out graphics. 200 | // Some visual data (such as outlines) will need to be pre-calculated for rendering order. 201 | function renderData(map) { 202 | var opts = map.options; 203 | var tooltip = template(opts.tooltip); 204 | var rows = {}; 205 | 206 | // Convert data rows into a hash keyed by id: 207 | for (var i = 0; i < opts.rows.length; i++) { 208 | rows[String(opts.rows[i].id)] = opts.rows[i]; 209 | } 210 | 211 | for (i = 0; i < map.geodata.length; i++) { 212 | var geo = map.geodata[i].properties || {}; 213 | var row = rows[String(geo.id)]; 214 | 215 | if (row) { 216 | if (opts.heat_scale) { 217 | geo.fill_color = map.heat(map.getRowValue('fill_color', row)); 218 | } else { 219 | geo.fill_color = map.getStyle('fill_color', row); 220 | } 221 | 222 | geo.stroke_color = map.getStyle('stroke_color', row); 223 | geo.stroke_size = map.getStyle('stroke_size', row); 224 | geo.tooltip = tooltip(row); 225 | } 226 | } 227 | 228 | // Sort geographies by stroke size: 229 | map.geodata.sort(function(a, b) { 230 | return a.properties.stroke_size - b.properties.stroke_size; 231 | }); 232 | } 233 | 234 | // Render Headers 235 | // 236 | // Renders the map's header and subhead 237 | function renderHeaders(map) { 238 | var opts = map.options; 239 | var header = map.el.header 240 | .attr('x', opts.width/2) 241 | .attr('y', map._y) 242 | .style('dominant-baseline', 'hanging') 243 | .style('text-anchor', 'middle') 244 | .style('font', opts.header_font) 245 | .style('fill', opts.font_color) 246 | .text(opts.header); 247 | 248 | // Increment Y-rendering position: 249 | map._y += header.node().getBBox().height + 20; 250 | } 251 | 252 | // Render Geography 253 | // 254 | // Renders all map geography shapes with their colors: 255 | function renderGeography(map) { 256 | var g = map.el.map; 257 | var opts = map.options; 258 | var pad = 20; 259 | 260 | var geo = g.selectAll('path') 261 | .data(map.geodata); 262 | 263 | geo 264 | .enter() 265 | .insert('path'); 266 | 267 | geo 268 | .attr('data-id', function(d) { return d.id; }) 269 | .each(function(d) { 270 | var el = d3.select(this); 271 | var p = d.properties; 272 | 273 | el.attr('fill', p.fill_color || opts.fill_color); 274 | el.attr('stroke', p.stroke_color || opts.stroke_color); 275 | el.attr('stroke-width', p.stroke_size || opts.stroke_size); 276 | if (p.tooltip) el.attr('data-tooltip', p.tooltip); 277 | }) 278 | .attr('d', map.path); 279 | 280 | geo 281 | .exit() 282 | .remove(); 283 | 284 | // Scale and position map centered within map view: 285 | var bbox = g.node().getBBox(); 286 | var maxWidth = opts.width - (pad * 2); 287 | var scale = maxWidth / bbox.width; 288 | var offsetX = pad - (bbox.x * scale); 289 | var offsetY = map._y - (bbox.y * scale); 290 | g.attr('transform', 'translate('+offsetX+','+offsetY+') scale('+scale+')'); 291 | 292 | map._y += Math.round(bbox.height * scale) + pad; 293 | } 294 | 295 | // Legend Reset 296 | // Removes outdated legend display before rendering new graphics. 297 | function resetLegend(map) { 298 | if (map.el.defs) map.el.defs.remove(); 299 | map.el.legend.html(''); 300 | } 301 | 302 | // Render Legend (Cohorts) 303 | // Renders the cohort-color swatch grid & labels. 304 | function renderCohortLegend(map) { 305 | resetLegend(map); 306 | var opts = map.options; 307 | var legend = map.el.legend; 308 | var data = opts.fills.concat(opts.strokes).filter(function(d) { return d.inLegend; }); 309 | var maxWidth = 0; 310 | var swatch = 20; 311 | var pad = 20; 312 | 313 | // Configure swatch rects: 314 | var swatches = legend.selectAll('rect').data(data); 315 | swatches.enter().append('rect'); 316 | swatches.exit().remove(); 317 | 318 | // Configure label texts: 319 | var labels = legend.selectAll('text').data(data); 320 | labels.enter().append('text'); 321 | labels.exit().remove(); 322 | 323 | // Set text for each label, then find maximum width label: 324 | labels 325 | .text(function(d) { return d.label; }) 326 | .attr('style', 'font:'+opts.legend_font+';fill:'+opts.font_color) 327 | .each(function(d) { 328 | maxWidth = Math.max(maxWidth, this.getComputedTextLength()); 329 | }); 330 | 331 | // Calculate minimum allowed column width, then balance column count: 332 | maxWidth = Math.round(swatch + 10 + maxWidth + pad); 333 | var layout = columnLayout(data.length, maxWidth, opts.width * 0.66); 334 | 335 | // Layout swatches: 336 | swatches 337 | .each(function(d, i) { 338 | if (d.type === 'fill') { 339 | // Fill swatches: 340 | d3.select(this) 341 | .attr('x', layout.x(i)) 342 | .attr('y', layout.y(i)) 343 | .attr('width', swatch) 344 | .attr('height', swatch) 345 | .attr('style', 'fill:'+d.color); 346 | 347 | } else { 348 | // Stroke swatches: 349 | var stroke = d.size; 350 | 351 | d3.select(this) 352 | .attr('x', layout.x(i) + stroke/2) 353 | .attr('y', layout.y(i) + stroke/2) 354 | .attr('width', swatch - stroke) 355 | .attr('height', swatch - stroke) 356 | .attr('style', 'fill:none;stroke:'+ d.color +';stroke-width:'+stroke); 357 | } 358 | }); 359 | 360 | // Layout labels: 361 | labels 362 | .each(function(d, i) { 363 | d3.select(this) 364 | .style('dominant-baseline', 'middle') 365 | .attr('x', swatch + 10 + layout.x(i)) 366 | .attr('y', layout.y(i) + swatch * 0.6); 367 | }); 368 | 369 | legend.attr('transform', 'translate(20,'+ map._y +')'); 370 | 371 | map._y += layout.h() + pad; 372 | } 373 | 374 | // Render Legend (Heat Scale) 375 | // Renders a heat gradient bar. 376 | function renderHeatLegend(map) { 377 | resetLegend(map); 378 | map.el.defs = map.el.svg.append('defs').html(''); 379 | 380 | var opts = map.options; 381 | var legend = map.el.legend; 382 | 383 | var gradient = map.el.defs 384 | .append('linearGradient') 385 | .attr('id', 'heat') 386 | .attr('x1', '0%') 387 | .attr('y1', '0%') 388 | .attr('x2', '100%') 389 | .attr('y2', '0%'); 390 | 391 | var ramp = legend 392 | .append('rect') 393 | .attr('width', 150) 394 | .attr('height', 20) 395 | .attr('fill', 'url(#heat)'); 396 | 397 | opts.fills.forEach(function(fill, i) { 398 | gradient 399 | .append('stop') 400 | .attr('offset', (i/(opts.fills.length-1) * 100)+'%') 401 | .attr('style', 'stop-color:'+fill.color); 402 | }); 403 | 404 | map._y += 20 + pad; 405 | } 406 | 407 | // Render Frame 408 | // 409 | // Renders the background rectangle fill and SVG bounding box. 410 | function renderFrame(map) { 411 | var opts = map.options; 412 | 413 | // Background fill rect: 414 | map.el.bg 415 | .attr('width', opts.width) 416 | .attr('height', map._y) 417 | .attr('fill', opts.background_color); 418 | 419 | // SVG frame rect: 420 | map.el.svg 421 | .attr('viewBox', '0 0 '+opts.width+' '+map._y); 422 | } 423 | 424 | // Render Brand 425 | // 426 | // Renders the brand mark in the lower-right corner. 427 | function renderBrand(map) { 428 | if (!map.brand) return; 429 | 430 | var opts = map.options; 431 | var brand = map.el.brand.attr('d', map.brand); 432 | var bbox = brand.node().getBBox(); 433 | var pad = 20; 434 | 435 | scale = (opts.width * 0.15) / bbox.width; 436 | offsetX = opts.width - Math.round(bbox.width * scale) - pad; 437 | offsetY = map._y - Math.round(bbox.height * scale) - pad; 438 | brand.attr('transform', 'translate('+offsetX+','+offsetY+') scale('+scale+')'); 439 | } 440 | 441 | function template(str) { 442 | // Generate a reusable function that will serve as a template 443 | // generator (and which will be cached). 444 | return new Function("o", 445 | "var p=[];" + 446 | 447 | // Introduce the data as local variables using with(){} 448 | "with(o){p.push('" + 449 | 450 | // Convert the template into pure JavaScript 451 | str 452 | .replace(/[\r\t\n]/g, " ") 453 | .split("<%").join("\t") 454 | .replace(/((^|%>)[^\t]*)'/g, "$1\r") 455 | .replace(/\t=(.*?)%>/g, "',$1,'") 456 | .split("\t").join("');") 457 | .split("%>").join("p.push('") 458 | .split("\r").join("\\'") 459 | + "');}return p.join('');"); 460 | } 461 | 462 | // Column Layout Helper (for legend items) 463 | // --------------------------------------------------- 464 | // Used for rendering legend items as balanced columns. 465 | // Accepts a numer of legend items, a minimum item width, and a total range to fill. 466 | // Returns an object with X/Y calc functions optimized for: 467 | // - Minimum possible columns, 468 | // - Minimum possible rows, 469 | // - Maximum possible items in last row. 470 | function columnLayout(numItems, minItemWidth, range) { 471 | // Calculate maximum allowed columns: 472 | var cols = Math.floor(range / minItemWidth); 473 | var rows = Infinity; 474 | var widow; 475 | 476 | // Fewer items than allowed columns: 477 | if (numItems < cols) { 478 | 479 | cols = numItems; 480 | 481 | } else { 482 | 483 | // Calculate ideal column count: 484 | // Use hill-climbing to find fewest columns with fewest rows and fullest final row. 485 | for (var i = cols; i > 0; i--) { 486 | // Calculate row count and widow items for this column config: 487 | var r = Math.ceil(numItems / i); 488 | var w = numItems % i; 489 | 490 | // Stop searching if we've exceeded minimum row count: 491 | // (we're count down, so we know we have surpassed minimum rows now) 492 | if (r > rows) break; 493 | 494 | // Record new minimum row counts, 495 | // and reset widow counter for each new row threshold reached: 496 | if (r !== rows) { 497 | rows = r; 498 | widow = -Infinity; 499 | } 500 | 501 | // Keep column count if there are no widows, 502 | // or if widow count is higher than previous best: 503 | // (we want exactly zero widows, or else as many hanging items as possible) 504 | if (w === 0 || w >= widow) { 505 | widow = w; 506 | cols = i; 507 | } 508 | } 509 | } 510 | 511 | // Return functions for calculating X and Y positions: 512 | return { 513 | rowHeight: 20, 514 | rowPad: 5, 515 | 516 | x: function(i) { 517 | return Math.floor(range / cols) * (i % cols); 518 | }, 519 | 520 | y: function(i) { 521 | return Math.floor(i / cols) * (this.rowHeight + this.rowPad); 522 | }, 523 | 524 | h: function() { 525 | return this.y(numItems-1) + this.rowHeight; 526 | } 527 | }; 528 | } 529 | 530 | }()); -------------------------------------------------------------------------------- /source/javascripts/mapper/views/editor-data.js: -------------------------------------------------------------------------------- 1 | // Map data form view (with drag-and-drop CSV) 2 | Mapper.views.EditorDataView = Backbone.View.extend({ 3 | el: '#editor-data', 4 | rowTmpl: _.template($('#editor-data-row').html(), {variable: 'd'}), 5 | 6 | initialize: function() { 7 | this.listenTo(this.collection, 'reset sort', this.render); 8 | this.listenTo(this.collection, 'change', this.renderRange); 9 | }, 10 | 11 | // Create function to build data-type select menu: 12 | // (kinda gross, I know...) 13 | renderTypeSelect: function(fieldName) { 14 | var opts = [''); 25 | return opts.join(''); 26 | }, 27 | 28 | // Renders all data into the grid: 29 | render: _.debounce(function() { 30 | var fields = _.without(this.model.get('columnNames'), 'id'); 31 | var head = 'id'; 32 | var self = this; 33 | 34 | // Build table header row: 35 | _.each(fields, function(field) { 36 | head += ''+ field +''+ this.renderTypeSelect(field) +''; 37 | }, this); 38 | 39 | // Build all table body rows: 40 | var body = this.collection.reduce(function(memo, model) { 41 | return memo += this.rowTmpl({fields: fields, model: model}); 42 | }, '', this); 43 | 44 | // Populate table head and body: 45 | this.$('thead').html(''+head+''); 46 | this.$('tbody').html(body); 47 | this.renderRange(); 48 | }, 5), 49 | 50 | renderRange: function() { 51 | var min = Infinity; 52 | var max = -Infinity; 53 | 54 | this.collection.each(function(geo) { 55 | var value = geo.get('value'); 56 | if (!isNaN(value)) { 57 | min = Math.min(min, value); 58 | max = Math.max(max, value); 59 | } 60 | }); 61 | 62 | this.$('#data-range').html('Value Min: '+min+', Max: '+max); 63 | }, 64 | 65 | events: { 66 | 'click a.sort': 'onSort', 67 | 'change input': 'onValue', 68 | 'change select': 'onDataType', 69 | 'dragover #data-dropzone': 'onZoneOver', 70 | 'dragleave #data-dropzone': 'onZoneOut', 71 | 'drop #data-dropzone': 'onZoneDrop' 72 | }, 73 | 74 | // Collection data-transfer settings from event object: 75 | getDataTransfer: function(evt) { 76 | evt.stopPropagation(); 77 | evt.preventDefault(); 78 | return evt.originalEvent.dataTransfer || null; 79 | }, 80 | 81 | // Triggered when dragging file over the CSV zone: 82 | onZoneOver: function(evt) { 83 | var dataTransfer = this.getDataTransfer(evt); 84 | if (dataTransfer) { 85 | dataTransfer.dropEffect = 'copy'; 86 | this.$('#data-dropzone').addClass('pulse'); 87 | } 88 | }, 89 | 90 | // Triggered when dragging a file out of CSV zone: 91 | onZoneOut: function(evt) { 92 | this.$('#data-dropzone').removeClass('pulse'); 93 | }, 94 | 95 | // Triggered when dropping a file on the CSV zone: 96 | onZoneDrop: function(evt) { 97 | var dataTransfer = this.getDataTransfer(evt); 98 | if (dataTransfer && dataTransfer.files.length) { 99 | this.collection.loadCSV(dataTransfer.files[0]); 100 | this.onZoneOut(); 101 | } 102 | }, 103 | 104 | onSort: function(evt) { 105 | this.collection.comparator = this.$(evt.target).text(); 106 | this.collection.sort(); 107 | }, 108 | 109 | // Sets a value for a record field: 110 | onValue: function(evt) { 111 | var $field = this.$(evt.currentTarget); 112 | var geo = this.collection.get($field.attr('data-id')); 113 | if (geo) geo.set($field.attr('name'), $field.val()); 114 | }, 115 | 116 | // Sets the datatype associated with a column: 117 | onDataType: function(evt) { 118 | var $field = this.$(evt.currentTarget); 119 | this.model.columnType($field.attr('name'), $field.val()); 120 | } 121 | }); -------------------------------------------------------------------------------- /source/javascripts/mapper/views/editor-main.js: -------------------------------------------------------------------------------- 1 | Mapper.views.EditorMainView = Backbone.View.extend({ 2 | el: '#editor-main', 3 | 4 | initialize: function() { 5 | //this.setView('editor-settings'); 6 | this.setView('editor-style'); 7 | }, 8 | 9 | setView: function(tab) { 10 | this.$('a[data-editor-view]') 11 | .removeClass('active') 12 | .filter('[data-editor-view="'+tab+'"]') 13 | .addClass('active'); 14 | 15 | this.$('.m-editor-view') 16 | .hide() 17 | .filter('#'+tab) 18 | .show(); 19 | }, 20 | 21 | events: { 22 | 'click a[data-editor-view]': 'onTab' 23 | }, 24 | 25 | onTab: function(evt) { 26 | evt.preventDefault(); 27 | this.setView(this.$(evt.currentTarget).attr('data-editor-view')); 28 | } 29 | }); -------------------------------------------------------------------------------- /source/javascripts/mapper/views/editor-settings.js: -------------------------------------------------------------------------------- 1 | // Form view for full legend region: 2 | Mapper.views.MapSettingsView = Backbone.Epoxy.View.extend({ 3 | el: '#editor-settings' 4 | }); -------------------------------------------------------------------------------- /source/javascripts/mapper/views/editor-style-base.js: -------------------------------------------------------------------------------- 1 | Mapper.views.EditorStyleBaseView = Backbone.Epoxy.View.extend({ 2 | el: '#editor-style-base', 3 | }); -------------------------------------------------------------------------------- /source/javascripts/mapper/views/editor-style-list.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var EditorStyleItemView = Backbone.Epoxy.View.extend({ 4 | el: $('#style-list-item').html(), 5 | 6 | events: { 7 | 'click [data-ui="destroy"]': 'onDestroy', 8 | 'click [data-ui="up"]': 'onUp', 9 | 'click [data-ui="down"]': 'onDown' 10 | }, 11 | 12 | onDestroy: function() { 13 | this.model.collection.remove(this.model); 14 | }, 15 | 16 | onUp: function() { 17 | this.model.collection.shiftItem(this.model, -1); 18 | }, 19 | 20 | onDown: function() { 21 | this.model.collection.shiftItem(this.model, 1); 22 | } 23 | }); 24 | 25 | // Form view for full legend region: 26 | Mapper.views.EditorStyleListView = Backbone.Epoxy.View.extend({ 27 | itemView: EditorStyleItemView, 28 | 29 | initialize: function(opts) { 30 | _.extend(this, opts); 31 | }, 32 | 33 | events: { 34 | 'click [data-ui="add"]': 'onAdd' 35 | }, 36 | 37 | onAdd: function() { 38 | this.collection.add({type: this.type}); 39 | } 40 | }); 41 | 42 | }()); -------------------------------------------------------------------------------- /source/javascripts/mapper/views/map-preview.js: -------------------------------------------------------------------------------- 1 | // Map renderer: 2 | 3 | Mapper.exporting = { 4 | canvas: document.createElement("canvas"), 5 | render: _.debounce(function() { 6 | this.canvas.width = 1024; 7 | this.canvas.height = 1000; 8 | 9 | var version = Date.now(); 10 | var svg = document.querySelector('#map-preview svg'); 11 | svg.setAttributeNS(null, 'width', '1024px'); 12 | 13 | var xml = new XMLSerializer().serializeToString(svg); 14 | canvg(this.canvas, xml, { ignoreMouse: true, ignoreAnimation: true }); 15 | svg.setAttributeNS(null, 'width', '100%'); 16 | 17 | $('#export-svg').attr({ 18 | href: 'data:image/svg+xml;base64,'+window.btoa(xml), 19 | download: 'map-'+version+'.svg' 20 | }); 21 | 22 | $('#export-png').attr({ 23 | href: this.canvas.toDataURL(), 24 | download: 'map-'+version+'.png' 25 | }); 26 | 27 | }, 100) 28 | }; 29 | 30 | Mapper.views.MapRenderView = Backbone.View.extend({ 31 | el: '#map-preview', 32 | 33 | initialize: function(opts) { 34 | _.extend(this, opts); 35 | this.$el.find('#map-renderer').attr('id', this.settings.get('el')); 36 | this.renderer = new MapRenderer(); 37 | this.renderer.onData = _.bind(function(data) { 38 | data = _.each(data, function(d) { d.value = '0'; }); 39 | this.data.resetData(data); 40 | }, this); 41 | 42 | this.listenTo(this.data, 'reset change', this.render); 43 | this.listenTo(this.fills, 'add remove change sort', this.render); 44 | this.listenTo(this.strokes, 'add remove change sort', this.render); 45 | this.listenTo(this.settings, 'change', this.render); 46 | this.render(); 47 | }, 48 | 49 | render: _.debounce(function() { 50 | this.renderer.init(Mapper.getRenderConfig({rows: true})); 51 | Mapper.exporting.render(); 52 | }, 10) 53 | }); -------------------------------------------------------------------------------- /source/javascripts/renderer.js: -------------------------------------------------------------------------------- 1 | //= require "vendor/d3.v3.min" 2 | //= require "vendor/d3.times.projection" 3 | //= require "vendor/topojson.v1.min" 4 | //= require "mapper/render" 5 | //MapRenderer.prototype.brand = 'M110.674,3.528h3.474L114.564,2H71.629l-0.417,1.528h6.253c5.418,0,9.726,3.751,9.726,11.255 c0,4.168-1.807,9.587-4.724,16.118L54.816,92.316L48.008,12.56c-0.556-6.253,2.501-9.032,9.588-9.032h4.029L62.042,2H1.599 L1.043,3.528h3.891c4.724,0,6.531,2.918,7.086,8.615l10.699,103.101h25.428l42.518-90.039 C97.057,11.726,103.865,3.528,110.674,3.528z M105.672,115.799c-3.891,0-6.253-1.25-6.253-7.643c0-8.059,2.918-23.76,6.114-38.072 c0.417,6.671,5.002,13.201,11.811,13.201c1.667,0,3.057-0.139,4.446-0.418C115.537,110.103,113.036,115.799,105.672,115.799z M226.696,61.608c8.06,0,13.201-6.669,13.201-14.173c0-6.392-4.586-11.116-11.116-11.116c-11.811,0-17.369,9.31-27.096,26.539 c-2.084-10.699-6.947-24.732-19.452-24.732c-14.035,0-30.152,20.008-45.02,32.375c-6.671,5.558-14.174,9.17-20.148,9.17 c-6.113,0-9.727-6.253-9.727-17.229c4.308-17.924,6.67-22.648,13.339-22.648c4.585,0,6.531,2.64,6.531,8.059 c0,5.697-1.251,15.424-3.752,27.512c6.67-2.084,16.674-10.421,25.011-19.452c-4.446-10.56-13.895-17.786-27.651-17.786 c-25.427,0-47.659,22.788-47.659,48.354c0,17.646,12.505,30.985,32.097,30.985c32.375,0,45.854-28.067,45.854-47.521 c0-2.779-0.139-4.862-0.417-7.364c5.003-5.419,11.394-10.56,16.674-10.56c5.975,0,10.699,15.006,15.423,37.656 c-4.168,4.585-8.337,13.478-10.421,15.006c-0.834-8.059-6.113-13.061-13.199-13.061c-7.921,0-13.479,7.503-13.479,13.895 c0,7.226,5.002,11.949,11.532,11.949c13.756,0,17.647-13.061,26.262-24.594c2.64,12.367,8.754,24.594,19.313,24.594 c12.506,0,24.178-10.699,30.152-18.341l-1.111-1.807c-3.891,3.752-7.643,6.253-11.95,6.253c-7.781,0-13.339-16.813-17.646-37.1 c2.5-3.473,6.53-12.228,9.31-15.285C213.496,54.8,217.525,61.608,226.696,61.608z'; -------------------------------------------------------------------------------- /source/javascripts/vendor/backbone.epoxy.js: -------------------------------------------------------------------------------- 1 | // Backbone.Epoxy 1.2.2 2 | // (c) 2013 Greg MacWilliam 3 | // Freely distributed under the MIT license 4 | // http://epoxyjs.org 5 | (function(t,e){"undefined"!=typeof exports?module.exports=e(require("underscore"),require("backbone")):"function"==typeof define&&define.amd?define(["underscore","backbone"],e):e(t._,t.Backbone)})(this,function(t,e){function n(t,e,n){return t._super.prototype[e].apply(t,n)}function i(e,n,o,r){for(var s in n)if(n.hasOwnProperty(s)){var u=n[s];if(e.hasComputed(s)){if(r.length&&t.contains(r,s))throw"Recursive setter: "+r.join(" > ");u=e.c()[s].set(u),u&&b(u)&&(o=i(e,u,o,r.concat(s)))}else o[s]=u}return o}function o(e,n,i,o){i=i||{},i.get&&w(i.get)&&(i._get=i.get),i.set&&w(i.set)&&(i._set=i.set),delete i.get,delete i.set,t.extend(this,i),this.model=e,this.name=n,this.deps=this.deps||[],o||this.init()}function r(e){return w(e)?e():(b(e)&&(e=t.clone(e),t.each(e,function(t,n){e[n]=r(t)})),e)}function s(t){return w(t)?{set:t}:t}function u(e){return function(){var n=arguments,i=w(e)?e:e.get,o=e.set;return function(e){return y(e)?i.apply(this,t.map(n,r)):n[0]((o?o:i).call(this,e))}}}function c(e,n,i,o,r){return(e=t.result(e,o))?(C(e)?(r=r?r+"_":"",n["$"+o]=function(){return F&&F.push([e,"change"]),e},t.each(e.toJSON({computed:!0}),function(t,o){n[r+o]=function(t){return a(e,o,t,i)}})):x(e)&&(n["$"+o]=function(){return F&&F.push([e,"reset add remove sort update"]),e}),e):void 0}function a(e,n,i,o){if(F&&F.push([e,"change:"+n]),!y(i)){if(!b(i)||_(i)||t.isDate(i)){var r=i;i={},i[n]=r}return o&&o.save?e.save(i,o):e.set(i,o)}return e.get(n)}function h(t,e){if(":el"===e)return t.$el;var n=t.$(e);return t.$el.is(e)&&(n=n.add(t.$el)),n}function l(e,n,i,o,r,s){try{var u=V[i]||(V[i]=Function("$f","$c","with($f){with($c){return{"+i+"}}}")),c=u(s,o)}catch(a){throw'Error parsing bindings: "'+i+'"\n>> '+a}var h=t.map(t.union(c.events||[],["change"]),function(t){return t+".epoxy"}).join(" ");t.each(c,function(t,i){if(r.hasOwnProperty(i))e.b().push(new p(e,n,r[i],t,h,o,c));else if(!q.hasOwnProperty(i))throw'binding handler "'+i+'" is not defined.'})}function f(t,e,n){return t&&t.hasOwnProperty(e)?y(n)?r(t[e]):t[e](n):void 0}function d(t,e){var n=[];if(e&&t)for(var i=0,o=e.length;o>i;i++)n.push(e[i]in t?t[e[i]]():null);return n}function p(e,n,i,o,s,u,c){var a=this,h=n[0].tagName.toLowerCase(),l="input"==h||"select"==h||"textarea"==h||"true"==n.prop("contenteditable"),f=[],d=function(t){a.set(a.$el,r(o),t)};if(a.view=e,a.$el=n,a.evt=s,t.extend(a,i),o=a.init(a.$el,r(o),u,c)||o,F=f,d(),F=null,l&&i.get&&w(o)&&a.$el.on(s,function(t){o(a.get(a.$el,r(o),t))}),f.length)for(var p=0,g=f.length;g>p;p++)a.listenTo(f[p][0],f[p][1],d)}var g,v=e.Epoxy={},m=Array.prototype,y=t.isUndefined,w=t.isFunction,b=t.isObject,_=t.isArray,C=function(t){return t instanceof e.Model},x=function(t){return t instanceof e.Collection},$=function(){},O={mixin:function(t){t=t||{};for(var e in this.prototype)"bindings"===e&&t.bindings||this.prototype.hasOwnProperty(e)&&"constructor"!==e&&(t[e]=this.prototype[e]);return t}},k=["computeds"];v.Model=e.Model.extend({_super:e.Model,constructor:function(e,i){t.extend(this,t.pick(i||{},k)),n(this,"constructor",arguments),this.initComputeds(e,i)},getCopy:function(e){return t.clone(this.get(e))},get:function(t){return g&&g.push(["change:"+t,this]),this.hasComputed(t)?this.c()[t].get():n(this,"get",arguments)},set:function(e,o,r){var s=e;s&&!b(s)?(s={},s[e]=o):r=o,r=r||{};var u=this._setting=[];r.unset||(s=i(this,s,{},[])),delete this._setting;var c=n(this,"set",[s,r]);return r.silent||(!this.hasChanged()&&u.length&&this.trigger("change",this),t.each(u,function(t){this.trigger.apply(this,t)},this)),c},toJSON:function(e){var i=n(this,"toJSON",arguments);return e&&e.computed&&t.each(this.c(),function(t,e){i[e]=t.value}),i},destroy:function(){return this.clearComputeds(),n(this,"destroy",arguments)},c:function(){return this._c||(this._c={})},initComputeds:function(e){this.clearComputeds();var n=t.result(this,"computeds")||{};n=t.extend(n,t.pick(e||{},t.keys(n))),t.each(n,function(t,e){t._init=1,this.addComputed(e,t)},this),t.invoke(this.c(),"init")},addComputed:function(t,e,n){this.removeComputed(t);var i=e,r=i._init;if(w(e)){var s=2;i={},i._get=e,w(n)&&(i._set=n,s++),i.deps=m.slice.call(arguments,s)}return this.c()[t]=new o(this,t,i,r),this},hasComputed:function(t){return this.c().hasOwnProperty(t)},removeComputed:function(t){return this.hasComputed(t)&&(this.c()[t].dispose(),delete this.c()[t]),this},clearComputeds:function(){for(var t in this.c())this.removeComputed(t);return this},modifyArray:function(t,e,n){var i=this.get(t);if(_(i)&&w(m[e])){var o=m.slice.call(arguments,2),r=m[e].apply(i,o);return n=n||{},n.silent||this.trigger("change:"+t+" change",this,m,n),r}return null},modifyObject:function(t,e,n,i){var o=this.get(t),r=!1;return b(o)?(i=i||{},y(n)&&o.hasOwnProperty(e)?(delete o[e],r=!0):o[e]!==n&&(o[e]=n,r=!0),r&&!i.silent&&this.trigger("change:"+t+" change",this,o,i),o):null}},O),t.extend(o.prototype,e.Events,{init:function(){var e={},n=g=[];this.get(!0),g=null,n.length&&(t.each(n,function(n){var i=n[0],o=n[1];e[i]?t.contains(e[i],o)||e[i].push(o):e[i]=[o]}),t.each(e,function(e,n){for(var i=0,o=e.length;o>i;i++)this.listenTo(e[i],n,t.bind(this.get,this,!0))},this))},val:function(t){return this.model.get(t)},get:function(e){if(e===!0&&this._get){var n=this._get.apply(this.model,t.map(this.deps,this.val,this));this.change(n)}return this.value},set:function(t){if(this._get){if(this._set)return this._set.apply(this.model,arguments);throw"Cannot set read-only computed attribute."}return this.change(t),null},change:function(e){if(!t.isEqual(e,this.value)){this.value=e;var n=["change:"+this.name,this.model,e];this.model._setting?this.model._setting.push(n):(n[0]+=" change",this.model.trigger.apply(this.model,n))}},dispose:function(){this.stopListening(),this.off(),this.model=this.value=null}});var P={optionText:"label",optionValue:"value"},V={},B={attr:s(function(t,e){t.attr(e)}),checked:s({get:function(e,n){var i=!!e.prop("checked"),o=e.val();if(this.isRadio(e))return o;if(_(n)){n=n.slice();var r=t.indexOf(n,o);return i&&0>r?n.push(o):!i&&r>-1&&n.splice(r,1),n}return i},set:function(e,n){var i=!!n;this.isRadio(e)?i=n==e.val():_(n)&&(i=t.contains(n,e.val())),e.prop("checked",i)},isRadio:function(t){return"radio"===t.attr("type").toLowerCase()}}),classes:s(function(e,n){t.each(n,function(t,n){e.toggleClass(n,!!t)})}),collection:s({init:function(t,e){if(!x(e))throw'Binding "collection" requires a Collection.';if(!w(this.view.itemView))throw'Binding "collection" requires an itemView.';this.v={}},set:function(e,n,i){var o,r=this.v,s=this.view.itemView,u=n.models,c=F;if(F=null,i=i||n,C(i))if(r.hasOwnProperty(i.cid))r[i.cid].remove(),delete r[i.cid];else{r[i.cid]=o=new s({model:i,collectionView:this.view});var a=t.indexOf(u,i),h=e.children();h.length>a?h.eq(a).before(o.$el):e.append(o.$el)}else if(x(i)){var l=u.length===t.size(r)&&n.every(function(t){return r.hasOwnProperty(t.cid)});e.children().detach();var f=document.createDocumentFragment();l?n.each(function(t){f.appendChild(r[t.cid].el)}):(this.clean(),n.each(function(t){r[t.cid]=o=new s({model:t,collectionView:this.view}),f.appendChild(o.el)})),e.append(f)}F=c},clean:function(){for(var t in this.v)this.v.hasOwnProperty(t)&&(this.v[t].remove(),delete this.v[t])}}),css:s(function(t,e){t.css(e)}),disabled:s(function(t,e){t.prop("disabled",!!e)}),enabled:s(function(t,e){t.prop("disabled",!e)}),html:s(function(t,e){t.html(e)}),options:s({init:function(t,e,n,i){this.e=i.optionsEmpty,this.d=i.optionsDefault,this.v=i.value},set:function(e,n){var i=this,o=r(i.e),s=r(i.d),u=r(i.v),c=x(n)?n.models:n,a=c.length,h=!0,l="";a||s||!o?(s&&(c=[s].concat(c)),t.each(c,function(t){l+=i.opt(t,a)})):(l+=i.opt(o,a),h=!1),e.html(l).prop("disabled",!h).val(u);var f=e.val();i.v&&!t.isEqual(u,f)&&i.v(f)},opt:function(t){var e=t,n=t,i=P.optionText,o=P.optionValue;return b(t)&&(e=C(t)?t.get(i):t[i],n=C(t)?t.get(o):t[o]),['"].join("")},clean:function(){this.d=this.e=this.v=0}}),template:s({init:function(e,n,i){var o=e.find("script,template");return this.t=t.template(o.length?o.html():e.html()),_(n)?t.pick(i,n):void 0},set:function(t,e){e=C(e)?e.toJSON({computed:!0}):e,t.html(this.t(e))},clean:function(){this.t=null}}),text:s({get:function(t){return t.text()},set:function(t,e){t.text(e)}}),toggle:s(function(t,e){t.toggle(!!e)}),value:s({get:function(t){return t.val()},set:function(t,e){try{t.val()+""!=e+""&&t.val(e)}catch(n){}}})},E={all:u(function(){for(var t=arguments,e=0,n=t.length;n>e;e++)if(!t[e])return!1;return!0}),any:u(function(){for(var t=arguments,e=0,n=t.length;n>e;e++)if(t[e])return!0;return!1}),length:u(function(t){return t.length||0}),none:u(function(){for(var t=arguments,e=0,n=t.length;n>e;e++)if(t[e])return!1;return!0}),not:u(function(t){return!t}),format:u(function(t){for(var e=arguments,n=1,i=e.length;i>n;n++)t=t.replace(RegExp("\\$"+n,"g"),e[n]);return t}),select:u(function(t,e,n){return t?e:n}),csv:u({get:function(t){return t+="",t?t.split(","):[]},set:function(t){return _(t)?t.join(","):t}}),integer:u(function(t){return t?parseInt(t,10):0}),decimal:u(function(t){return t?parseFloat(t):0})},q={events:1,optionsDefault:1,optionsEmpty:1};v.binding={allowedParams:q,addHandler:function(t,e){B[t]=s(e)},addFilter:function(t,e){E[t]=u(e)},config:function(e){t.extend(P,e)},emptyCache:function(){V={}}};var F,M=["viewModel","bindings","bindingFilters","bindingHandlers","bindingSources","computeds"];return v.View=e.View.extend({_super:e.View,constructor:function(e){t.extend(this,t.pick(e||{},M)),n(this,"constructor",arguments),this.applyBindings()},b:function(){return this._b||(this._b=[])},bindings:"data-bind",setterOptions:null,applyBindings:function(){this.removeBindings();var n=this,i=t.clone(t.result(n,"bindingSources")),o=n.bindings,r=n.setterOptions,a=t.clone(B),f=t.clone(E),p=n._c={};t.each(t.result(n,"bindingHandlers")||{},function(t,e){a[e]=s(t)}),t.each(t.result(n,"bindingFilters")||{},function(t,e){f[e]=u(t)}),n.model=c(n,p,r,"model"),n.viewModel=c(n,p,r,"viewModel"),n.collection=c(n,p,r,"collection"),n.collection&&n.collection.view&&(n.itemView=n.collection.view),i&&(t.each(i,function(t,e){i[e]=c(i,p,r,e,e)}),n.bindingSources=i),t.each(t.result(n,"computeds")||{},function(t,e){var i=w(t)?t:t.get,o=t.set,r=t.deps;p[e]=function(t){return!y(t)&&o?o.call(n,t):i.apply(n,d(n._c,r))}}),b(o)?t.each(o,function(t,e){var i=h(n,e);i.length&&l(n,i,t,p,a,f)}):h(n,"["+o+"]").each(function(){var t=e.$(this);l(n,t,t.attr(o),p,a,f)})},getBinding:function(t){return f(this._c,t)},setBinding:function(t,e){return f(this._c,t,e)},removeBindings:function(){if(this._c=null,this._b)for(;this._b.length;)this._b.pop().dispose()},remove:function(){this.removeBindings(),n(this,"remove",arguments)}},O),t.extend(p.prototype,e.Events,{init:$,get:$,set:$,clean:$,dispose:function(){this.clean(),this.stopListening(),this.$el.off(this.evt),this.$el=this.view=null}}),v}); 6 | -------------------------------------------------------------------------------- /source/javascripts/vendor/backbone.js: -------------------------------------------------------------------------------- 1 | (function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('