[
  {
    "path": ".eslintignore",
    "content": "node_modules\n*.cjs.js\n*.es.js\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  parserOptions: {\n    ecmaVersion: 2019,\n    sourceType: 'module',\n  },\n  env: {\n    es6: true,\n  },\n  extends: ['eslint-config-airbnb-base'],\n  rules: {\n    'no-nested-ternary': 0,\n    'import/no-extraneous-dependencies': 0,\n    'no-param-reassign': 0,\n  },\n};\n"
  },
  {
    "path": ".github/workflows/eslint.yml",
    "content": "name: Lint\n\non: push\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Check out Git repository\n        uses: actions/checkout@v2\n\n      - name: Set up Node.js\n        uses: actions/setup-node@v1\n        with:\n          node-version: 14\n\n      # ESLint and Prettier must be in `package.json`\n      - name: Install Node.js dependencies\n        run: npm install\n\n      - name: Run linters\n        uses: wearerequired/lint-action@v1\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n          # Enable linters\n          eslint: true"
  },
  {
    "path": ".github/workflows/npm-publish.yml",
    "content": "name: Publish to NPM\n\non:\n  push:\n    tags:\n      - '*'\n\njobs:\n  publish:\n    name: Publish to NPM\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v1\n      - uses: actions/setup-node@v1\n        with:\n          node-version: 14\n      - run: npm install\n      - uses: JS-DevTools/npm-publish@v1\n        with:\n          token: ${{ secrets.NPM_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "build/\nnode_modules\n*-10t.json\nbase*.json\n*.es.js\n*.cjs.js\n*.svg\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Daniel Kao\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Taiwan Atlas TopoJSON\n\nSimilar to the [topojson/us-atlas](https://github.com/topojson/us-atlas) project, this repository provides a topojson redistribution of the shapefiles provided by Taiwan's Ministry of the Interior. See [the demo](https://observablehq.com/@dkaoster/taiwan-map) for usage example.\n\nAll of these files are provided at a scale of 1:10 thousand.\n\n## File Reference\n\n<a href=\"#villages-10t.json\" name=\"villages-10t.json\">#</a> <b>villages-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/villages-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>villages</i>, <i>towns</i>, <i>counties</i>, and <i>nation</i>. The geometry is quantized and simplified, but not projected. This topology is derived from the Ministry of the Interior’s [村里界圖(TWD97經緯度)](https://data.gov.tw/dataset/7438). The town boundaries are computed by [merging](https://github.com/topojson/topojson-client/blob/master/README.md#merge) villages, the county boundaries by merging towns, and the nation boundary is computed by merging counties, ensuring a consistent topology.\n\n<a href=\"#villages-mercator-10t.json\" name=\"villages-mercator-10t.json\">#</a> <b>villages-mercator-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/villages-mercator-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>villages</i>, <i>towns</i>, <i>counties</i>, and <i>nation</i>. The geometry is quantized, simplified, and projected with the mercatorTw projection. This topology is derived from the Ministry of the Interior’s [村里界圖(TWD97經緯度)](https://data.gov.tw/dataset/7438). The town boundaries are computed by [merging](https://github.com/topojson/topojson-client/blob/master/README.md#merge) villages, the county boundaries by merging towns, and the nation boundary is computed by merging counties, ensuring a consistent topology. This file also contains a compBorders object for optionally drawing the borders of the composed areas.\n\n<a href=\"#towns-10t.json\" name=\"towns-10t.json\">#</a> <b>towns-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/towns-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>towns</i>, <i>counties</i>, and <i>nation</i>. The geometry is quantized and simplified, but not projected. This topology is derived from the Ministry of the Interior’s [鄉鎮市區界線(TWD97經緯度)](https://data.gov.tw/dataset/7441). The county boundaries are computed by [merging](https://github.com/topojson/topojson-client/blob/master/README.md#merge) towns and the nation boundaries by merging counties, ensuring a consistent topology.\n\n<a href=\"#towns-mercator-10t.json\" name=\"towns-mercator-10t.json\">#</a> <b>towns-mercator-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/towns-mercator-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>towns</i>, <i>counties</i>, and <i>nation</i>. The geometry is quantized, simplified, and projected with the mercatorTw projection. This topology is derived from the Ministry of the Interior’s [鄉鎮市區界線(TWD97經緯度)](https://data.gov.tw/dataset/7441). The county boundaries are computed by [merging](https://github.com/topojson/topojson-client/blob/master/README.md#merge) towns and the nation boundaries by merging counties, ensuring a consistent topology. This file also contains a compBorders object for optionally drawing the borders of the composed areas.\n\n<a href=\"#districts-10t.json\" name=\"districts-10t.json\">#</a> <b>districts-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/districts-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>districts</i> specifying legislative districts, <i>counties</i>, and <i>nation</i>. The geometry is quantized and simplified, but not projected. This topology is derived from the Ministry of the Interior’s [鄉鎮市區界線(TWD97經緯度)](https://data.gov.tw/dataset/7441) and combined via the districts specified in [this json file](https://github.com/dkaoster/taiwan-atlas/blob/master/utils/districts.json). The county boundaries are computed by [merging](https://github.com/topojson/topojson-client/blob/master/README.md#merge) districts and the nation boundaries by merging counties, ensuring a consistent topology.\n\n<a href=\"#districts-mercator-10t.json\" name=\"districts-mercator-10t.json\">#</a> <b>districts-mercator-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/districts-mercator-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>districts</i> specifying legislative districts, <i>counties</i>, and <i>nation</i>. The geometry is quantized, simplified, and projected with the mercatorTw projection. This topology is derived from the Ministry of the Interior’s [鄉鎮市區界線(TWD97經緯度)](https://data.gov.tw/dataset/7441) and combined via the districts specified in [this json file](https://github.com/dkaoster/taiwan-atlas/blob/master/utils/districts.json). The county boundaries are computed by [merging](https://github.com/topojson/topojson-client/blob/master/README.md#merge) districts and the nation boundaries by merging counties, ensuring a consistent topology. This file also contains a compBorders object for optionally drawing the borders of the composed areas.\n\n<a href=\"#counties-10t.json\" name=\"counties-10t.json\">#</a> <b>counties-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/counties-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>counties</i>, and <i>nation</i>. The geometry is quantized and simplified, but not projected. This topology is derived from the Ministry of the Interior’s [直轄市、縣市界線(TWD97經緯度)](https://data.gov.tw/dataset/7442). The nation boundaries are computed by [merging](https://github.com/topojson/topojson-client/blob/master/README.md#merge) counties, ensuring a consistent topology.\n\n<a href=\"#counties-mercator-10t.json\" name=\"counties-mercator-10t.json\">#</a> <b>counties-mercator-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/counties-mercator-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>counties</i> and <i>nation</i>. The geometry is quantized, simplified, and projected with the mercatorTw projection. This topology is derived from the Ministry of the Interior’s [直轄市、縣市界線(TWD97經緯度)](https://data.gov.tw/dataset/7442). The nation boundaries are computed by [merging](https://github.com/topojson/topojson-client/blob/master/README.md#merge) counties, ensuring a consistent topology. This file also contains a compBorders object for optionally drawing the borders of the composed areas.\n\n<a href=\"#nation-10t.json\" name=\"nation-10t.json\">#</a> <b>nation-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/nation-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>nation</i>. The geometry is quantized and simplified, but not projected. This topology is derived from the Ministry of the Interior’s [直轄市、縣市界線(TWD97經緯度)](https://data.gov.tw/dataset/7442).\n\n<a href=\"#nation-mercator-10t.json\" name=\"nation-mercator-10t.json\">#</a> <b>nation-mercator-10t.json</b> · [Download](https://cdn.jsdelivr.net/npm/taiwan-atlas/nation-mercator-10t.json \"Source\")\n\nA [TopoJSON file](https://github.com/topojson/topojson-specification/blob/master/README.md#21-topology-objects) containing the geometry collections <i>nation</i>. The geometry is quantized, simplified, and projected with the mercatorTw projection. This topology is derived from the Ministry of the Interior’s [直轄市、縣市界線(TWD97經緯度)](https://data.gov.tw/dataset/7442). This file also contains a compBorders object for optionally drawing the borders of the composed areas.\n\n<a href=\"#tw.objects.nation\" name=\"tw.objects.nation\">#</a> tw.objects<b>.nation</b>\n\n<img src=\"https://raw.githubusercontent.com/dkaoster/taiwan-atlas/master/img/nation.png\" width=\"50%\">\n\nThe nation object has two fields:\n- nation.properties.ID - \"TW\"\n- nation.properties.NAME - \"Taiwan\"\n\n<a href=\"#tw.objects.counties\" name=\"tw.objects.counties\">#</a> tw.objects<b>.counties</b>\n\n<img src=\"https://raw.githubusercontent.com/dkaoster/taiwan-atlas/master/img/counties.png\" width=\"50%\">\n\nThe county object has the following fields:\n- county.properties.COUNTYNAME - The name of the county in Chinese\n- county.properties.COUNTYENG - The name of the county in English\n- county.properties.COUNTYID - The character specifying id\n- county.properties.COUNTYCODE - The five digit county code\n\n<a href=\"#tw.objects.towns\" name=\"tw.objects.towns\">#</a> tw.objects<b>.towns</b>\n\n<img src=\"https://raw.githubusercontent.com/dkaoster/taiwan-atlas/master/img/towns.png\" width=\"50%\">\n\nThe town object has the following fields in addition to the county fields:\n- town.properties.TOWNNAME - The name of the county in Chinese\n- town.properties.TOWNENG - The name of the county in English\n- town.properties.TOWNID - The character specifying id\n- town.properties.TOWNCODE - The eight digit county code\n\n<a href=\"#tw.objects.districts\" name=\"tw.objects.districts\">#</a> tw.objects<b>.districts</b>\n\n<img src=\"https://raw.githubusercontent.com/dkaoster/taiwan-atlas/master/img/districts.png\" width=\"50%\">\n\nThe district object has the following fields in addition to the county fields:\n- district.properties.DISTRICTCODE - The eight digit county code dash (-) the district number\n\n<a href=\"#tw.objects.villages\" name=\"tw.objects.villages\">#</a> tw.objects<b>.villages</b>\n\n<img src=\"https://raw.githubusercontent.com/dkaoster/taiwan-atlas/master/img/villages.png\" width=\"50%\">\n\nThe village object has the following fields in addition to the town and county fields:\n- village.properties.VILLNAME - The name of the village in Chinese\n- village.properties.VILLENG - The name of the village in English\n- village.properties.VILLID - The village specifying id\n- village.properties.VILLCODE - The 11 digit county code\n\nThe compBorders object has the following fields:\n- compBorders.properties.BORDERLEVEL - The administrative level that this border encompasses.\n- compBorders.properties.NAME - The name in Chinese of the administrative area that this border encompasses.\n- compBorders.properties.ID - The id of the administrative area that this border encompasses.\n- compBorders.properties.CODE - The name of the administrative area that this border encompasses.\n- compBorders.properties.ENG - The name in English of the administrative area that this border encompasses.\n\n## MercatorTw Projection\n\n`mercatorTw.js` uses a Taiwan-centric composite projection of four [d3.geoMercator](https://github.com/d3/d3-geo#geoMercator) projections: One for the main island, and one for each of Penghu, Kinmen, Lienchiang, and Wuqiu respectively.\n\n`mercatorTw.getCompositionBorders()` returns a svg path string of the borders, given the current scale and translation.\n\nThis package exports the mercatorTw projection and can be used in your own projects.\n\n```js\nimport mercatorTw from 'taiwan-atlas';\n```\n\n## License\nMIT\n"
  },
  {
    "path": "compBordersGeo.js",
    "content": "// eslint-disable-next-line import/no-unresolved\nconst mercatorTw = require('./mercatorTw.cjs.js');\n\n// Initialize Projection\nlet merc = mercatorTw();\n\n// Read center from first argument or from defaultCenter\nconst translate = process.argv[2] && JSON.parse(process.argv[2]);\nif (translate) merc = merc.translate(translate);\n\n// Read scale from second argument or from defaultScale\nconst scale = process.argv[3] && parseInt(process.argv[3], 10);\nif (scale) merc = merc.scale(scale);\n\n// The properties that we will add to the box\nconst properties = {\n  lienchiang: {\n    BORDERLEVEL: 'COUNTY', NAME: '連江縣', ID: 'Z', CODE: '09007', ENG: 'Lienchiang County',\n  },\n  penghu: {\n    BORDERLEVEL: 'COUNTY', NAME: '澎湖縣', ID: 'X', CODE: '10016', ENG: 'Penghu County',\n  },\n  kinmen: {\n    BORDERLEVEL: 'COUNTY', NAME: '金門縣', ID: 'W', CODE: '09020', ENG: 'Kinmen County',\n  },\n  wuqiu: {\n    BORDERLEVEL: 'TOWN', NAME: '烏坵鄉', ID: 'W06', CODE: '09020060', ENG: 'Wuqiu Township',\n  },\n};\n\n// Generate the features\nconst features = merc.compositionBorderPoints()\n  .map((border) => ({\n    type: 'Feature',\n    geometry: { type: 'Polygon', coordinates: [border.coords] },\n    properties: properties[border.name],\n  }));\n\n// Print to stdout\nfeatures.forEach((feature) => {\n  process.stdout.write(JSON.stringify(feature));\n  process.stdout.write('\\n');\n});\n"
  },
  {
    "path": "generateimg.sh",
    "content": "#!/bin/bash\n\n# Create the border json\ntopo2geo compBorders=- < nation-mercator-10t.json > img/base-border.json\n\n# Villages\ntopo2geo villages=- < villages-mercator-10t.json > img/base-villages.json\ngeojson-merge img/base-villages.json img/base-border.json | geo2svg -o img/villages.svg -w 450 -h 600\nsvgexport img/villages.svg img/villages.png 2x \"path {stroke-width: 0.3px;}\"\n\n# Districts\ntopo2geo districts=- < districts-mercator-10t.json > img/base-districts.json\ngeojson-merge img/base-districts.json img/base-border.json | geo2svg -o img/districts.svg -w 450 -h 600\nsvgexport img/districts.svg img/districts.png 2x \"path {stroke-width: 0.5px;}\"\n\n# Towns\ntopo2geo towns=- < towns-mercator-10t.json > img/base-towns.json\ngeojson-merge img/base-towns.json img/base-border.json | geo2svg -o img/towns.svg -w 450 -h 600\nsvgexport img/towns.svg img/towns.png 2x \"path {stroke-width: 0.5px;}\"\n\n# Counties\ntopo2geo counties=- < counties-mercator-10t.json > img/base-counties.json\ngeojson-merge img/base-counties.json img/base-border.json | geo2svg -o img/counties.svg -w 450 -h 600\nsvgexport img/counties.svg img/counties.png 2x\n\n# Nation\ntopo2geo nation=- < nation-mercator-10t.json > img/base-nation.json\ngeojson-merge img/base-nation.json img/base-border.json | geo2svg -o img/nation.svg -w 450 -h 600\nsvgexport img/nation.svg img/nation.png 2x\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"taiwan-atlas\",\n  \"version\": \"2021.9.20\",\n  \"description\": \"Pre-built TopoJSON from the Ministry of the Interior.\",\n  \"main\": \"mercatorTw.cjs.js\",\n  \"jsnext:main\": \"mercatorTw.es.js\",\n  \"files\": [\n    \"*-10t.json\",\n    \"mercatorTw.cjs.js\",\n    \"mercatorTw.es.js\",\n    \"README.md\"\n  ],\n  \"scripts\": {\n    \"lint\": \"eslint .\",\n    \"generate:img\": \"npm run build && bash prepublish.sh && bash generateimg.sh\",\n    \"clean\": \"rimraf mercatorTw.cjs.js mercatorTw.es.js\",\n    \"build\": \"npm run clean && npm run build:cjs && npm run build:es\",\n    \"build:cjs\": \"rollup -c -o mercatorTw.cjs.js -f cjs\",\n    \"build:es\": \"rollup -c -o mercatorTw.es.js -f es\",\n    \"prepublishOnly\": \"npm run build && bash prepublish.sh\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/dkaoster/taiwan-atlas.git\"\n  },\n  \"author\": {\n    \"name\": \"Daniel Kao\",\n    \"url\": \"https://www.diplateevo.com/\"\n  },\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"topojson\",\n    \"geojson\",\n    \"shapefile\"\n  ],\n  \"bugs\": {\n    \"url\": \"https://github.com/dkaoster/taiwan-atlas/issues\"\n  },\n  \"homepage\": \"https://github.com/dkaoster/taiwan-atlas#readme\",\n  \"devDependencies\": {\n    \"@mapbox/geojson-merge\": \"^1.1.1\",\n    \"d3-geo-projection\": \"^3.0.0\",\n    \"eslint\": \"^7.14.0\",\n    \"eslint-config-airbnb-base\": \"^14.2.1\",\n    \"eslint-plugin-import\": \"^2.22.1\",\n    \"globby\": \"^11.0.1\",\n    \"mapshaper\": \"^0.6.44\",\n    \"ndjson-cli\": \"^0.3.1\",\n    \"rimraf\": \"^3.0.2\",\n    \"rollup\": \"^2.33.3\",\n    \"shapefile\": \"^0.6.6\",\n    \"svgexport\": \"^0.4.1\",\n    \"topojson-client\": \"^3.1.0\",\n    \"topojson-server\": \"^3.0.1\",\n    \"topojson-simplify\": \"^3.0.3\"\n  },\n  \"dependencies\": {\n    \"d3-geo\": \"^2.0.1\",\n    \"d3-path\": \"^2.0.0\"\n  }\n}\n"
  },
  {
    "path": "prepublish.sh",
    "content": "#!/bin/bash\n\nset -e\n\nrm -rvf *-10t.json base.json\nmkdir -p build\n\n# Crawl the data pages for the download links\n# Village URL\nvillageShpUrl=$(curl -Ls https://data.gov.tw/dataset/7438 | \\\n  # Find the link that has the SHP tag\n  grep -io '\"SHP\",\"contentUrl\":[^}]*\"}' | \\\n  # get the href tag\n  sed -E 's/.*contentUrl\":\"([^\"]+).*/\\1/g')\n\n# Town URL\ntownShpUrl=$(curl -Ls https://data.gov.tw/dataset/7441 | \\\n  # Find the link that has the SHP tag\n  grep -io '\"SHP\",\"contentUrl\":[^}]*\"}' | \\\n  # get the href tag\n  sed -E 's/.*contentUrl\":\"([^\"]+).*/\\1/g')\n\n# County URL\ncountyShpUrl=$(curl -Ls https://data.gov.tw/dataset/7442 | \\\n  # Find the link that has the SHP tag\n  grep -io '\"SHP\",\"contentUrl\":[^}]*\"}' | \\\n  # get the href tag\n  sed -E 's/.*contentUrl\":\"([^\"]+).*/\\1/g')\n\n# Download and extract the archives\nif [ ! -f build/village.zip ]; then\n  curl -Lo build/village.zip \"${villageShpUrl}\"\n  unzip -od build build/village.zip\nfi\n\n# Download and extract the archives\nif [ ! -f build/town.zip ]; then\n  curl -Lo build/town.zip \"${townShpUrl}\"\n  unzip -od build build/town.zip\nfi\n\n# Download and extract the archives\nif [ ! -f build/county.zip ]; then\n  curl -Lo build/county.zip \"${countyShpUrl}\"\n  unzip -od build build/county.zip\nfi\n\n###############################################################################\n# Generate topojson files\n\n# Boundaries for everything we care about\nbbox=117.663,21.577,122.0202,26.671\n\n# Village file\ngeo2topo -q 1e10 -n villages=<( \\\n    shp2json -n --encoding=UTF-8 build/VILLAGE*.shp \\\n      | ndjson-filter '!!d.properties.VILLNAME') \\\n  | topomerge towns=villages -k 'd.properties.TOWNCODE' \\\n  | topomerge counties=towns -k 'd.properties.COUNTYCODE' \\\n  | topomerge nation=counties \\\n  | toposimplify -f -s 1e-10 \\\n  | node ./properties.js \\\n  > villages-10t.json\n\n# Use mapshaper to remove extra slivers and islands outside of the boundaries.\nmapshaper -i villages-10t.json -clip bbox=${bbox} -filter-slivers -o force format=topojson villages-10t.json\nmapshaper -i villages-10t.json -clean target=* -o force format=topojson villages-10t.json\n\n# Town file\ngeo2topo -q 1e10 -n towns=<( \\\n    shp2json -n --encoding=UTF-8 build/TOWN*.shp \\\n      | ndjson-filter '!!d.properties.TOWNNAME') \\\n  | topomerge counties=towns -k 'd.properties.COUNTYCODE' \\\n  | topomerge nation=counties \\\n  | toposimplify -f -s 1e-10 \\\n  | node ./properties.js \\\n  > towns-10t.json\n\n# Use mapshaper to remove extra slivers and islands outside of the boundaries.\nmapshaper -i towns-10t.json -clip bbox=${bbox} -filter-slivers -o force format=topojson towns-10t.json\nmapshaper -i towns-10t.json -clean target=* -o force format=topojson towns-10t.json\n\n# County file\ngeo2topo -q 1e10 -n counties=<( \\\n    shp2json -n --encoding=UTF-8 build/COUNTY*.shp \\\n      | ndjson-filter '!!d.properties.COUNTYNAME') \\\n  | topomerge nation=counties \\\n  | toposimplify -f -s 1e-10 \\\n  | node ./properties.js \\\n  > counties-10t.json\n\n# Use mapshaper to remove extra slivers and islands outside of the boundaries.\nmapshaper -i counties-10t.json -clip bbox=${bbox} -filter-slivers -o force format=topojson counties-10t.json\nmapshaper -i counties-10t.json -clean target=* -o force format=topojson counties-10t.json\n\n# Use mapshaper to remove layers of detail we don't want for nation\nmapshaper -i counties-10t.json -drop target=counties -o format=topojson target=* nation-10t.json\n\n# District file\ngeo2topo -q 1e10 -n villages=<( \\\n    shp2json -n --encoding=UTF-8 build/VILLAGE*.shp \\\n      | ndjson-filter '!!d.properties.VILLNAME') \\\n  | DISTRICTS=\"true\" node ./properties.js \\\n  | topomerge districts=villages -k 'd.properties.DISTRICTCODE' \\\n  | topomerge counties=districts -k 'd.properties.COUNTYCODE' \\\n  | topomerge nation=counties \\\n  | toposimplify -f -s 1e-10 \\\n  > districts-10t.json\n\n# Use mapshaper to remove extra slivers and islands outside of the boundaries.\nmapshaper -i districts-10t.json -clip bbox=${bbox} -filter-slivers -o force format=topojson districts-10t.json\nmapshaper -i districts-10t.json -clean target=* -o force format=topojson districts-10t.json\n\n# Use mapshaper to remove layers of detail we don't want for district\nmapshaper -i districts-10t.json -drop target=villages -o force format=topojson target=* districts-10t.json\n\n# Village mercator projections\ngeo2topo -q 1e7 -n \\\n  villages=<(shp2json -n --encoding=UTF-8 build/VILLAGE*.shp \\\n    | ndjson-filter '!!d.properties.VILLNAME' \\\n    | geoproject --require mercatorTw='./mercatorTw.cjs' -n 'mercatorTw()') \\\n  compBorders=<(node compBordersGeo.js) \\\n  | topomerge towns=villages -k 'd.properties.TOWNCODE' \\\n  | topomerge counties=towns -k 'd.properties.COUNTYCODE' \\\n  | topomerge nation=counties \\\n  | toposimplify -f -s 1e-6 \\\n  | node ./properties.js \\\n  > villages-mercator-10t.json\n\n# Use mapshaper to remove extra slivers and islands outside of the boundaries.\nmapshaper -i villages-mercator-10t.json -filter-slivers -o force format=topojson villages-mercator-10t.json\nmapshaper -i villages-mercator-10t.json -clean target=* -o force format=topojson villages-mercator-10t.json\n\n# Town mercator projections\ngeo2topo -q 1e7 -n \\\n  towns=<(shp2json -n --encoding=UTF-8 build/TOWN*.shp \\\n    | ndjson-filter '!!d.properties.TOWNNAME' \\\n    | geoproject --require mercatorTw='./mercatorTw.cjs' -n 'mercatorTw()') \\\n  compBorders=<(node compBordersGeo.js) \\\n  | topomerge counties=towns -k 'd.properties.COUNTYCODE' \\\n  | topomerge nation=counties \\\n  | toposimplify -f -s 1e-6 \\\n  | node ./properties.js \\\n  > towns-mercator-10t.json\n\n# Use mapshaper to remove extra slivers and islands outside of the boundaries.\nmapshaper -i towns-mercator-10t.json -filter-slivers -o force format=topojson towns-mercator-10t.json\nmapshaper -i towns-mercator-10t.json -clean target=* -o force format=topojson towns-mercator-10t.json\n\n# County mercator projections\ngeo2topo -q 1e7 -n \\\n  counties=<(shp2json -n --encoding=UTF-8 build/COUNTY*.shp \\\n    | ndjson-filter '!!d.properties.COUNTYNAME' \\\n    | geoproject --require mercatorTw='./mercatorTw.cjs' -n 'mercatorTw()') \\\n  compBorders=<(node compBordersGeo.js) \\\n  | topomerge nation=counties \\\n  | toposimplify -f -s 1e-6 \\\n  | node ./properties.js \\\n  > counties-mercator-10t.json\n\n# Use mapshaper to remove extra slivers and islands outside of the boundaries.\nmapshaper -i counties-mercator-10t.json -filter-slivers -o force format=topojson counties-mercator-10t.json\nmapshaper -i counties-mercator-10t.json -clean target=* -o force format=topojson counties-mercator-10t.json\n\n# Use mapshaper to remove layers of detail we don't want for nation\nmapshaper -i counties-mercator-10t.json -drop target=counties -o format=topojson target=* nation-mercator-10t.json\n\n# District mercator projections\ngeo2topo -q 1e7 -n \\\n  villages=<(shp2json -n --encoding=UTF-8 build/VILLAGE*.shp \\\n    | ndjson-filter '!!d.properties.VILLNAME' \\\n    | geoproject --require mercatorTw='./mercatorTw.cjs' -n 'mercatorTw()') \\\n  compBorders=<(node compBordersGeo.js) \\\n  | DISTRICTS=\"true\" node ./properties.js \\\n  | topomerge districts=villages -k 'd.properties.DISTRICTCODE' \\\n  | topomerge counties=districts -k 'd.properties.COUNTYCODE' \\\n  | topomerge nation=counties \\\n  | toposimplify -f -s 1e-6 \\\n  > districts-mercator-10t.json\n\n# Use mapshaper to remove extra slivers and islands outside of the boundaries.\nmapshaper -i districts-mercator-10t.json -filter-slivers -o force format=topojson districts-mercator-10t.json\nmapshaper -i districts-mercator-10t.json -clean target=* -o force format=topojson districts-mercator-10t.json\n\n# Use mapshaper to remove layers of detail we don't want for district\nmapshaper -i districts-mercator-10t.json -drop target=villages -o force format=topojson target=* districts-mercator-10t.json\n"
  },
  {
    "path": "properties.js",
    "content": "const shapefile = require('shapefile');\nconst globby = require('globby');\nconst districts = require('./utils/districts.json');\n\n// Parse the piped in topojson\nfunction parseInput() {\n  return new Promise((resolve, reject) => {\n    const chunks = [];\n    process.stdin\n      .on('data', (chunk) => chunks.push(chunk))\n      .on('end', () => {\n        try { resolve(JSON.parse(chunks.join(''))); } catch (error) { reject(error); }\n      })\n      .setEncoding('utf8');\n  });\n}\n\n// 臺 > 台\nfunction fixTai(obj) {\n  return { ...obj, COUNTYNAME: obj.COUNTYNAME.replace('臺', '台') };\n}\n\n// Generated modified properties\nfunction output([topology, towns, counties]) {\n  const townsMap = new Map(\n    towns.features.map((d) => [d.properties.TOWNCODE, d.properties]),\n  );\n  const countiesMap = new Map(\n    counties.features.map((d) => [d.properties.COUNTYCODE, d.properties]),\n  );\n\n  // Process village properties\n  if (topology.objects.villages) {\n    // eslint-disable-next-line no-restricted-syntax\n    for (const village of topology.objects.villages.geometries) {\n      village.properties = fixTai(village.properties);\n      village.properties.TOWNENG = townsMap.get(village.properties.TOWNCODE).TOWNENG;\n      village.properties.COUNTYENG = countiesMap.get(village.properties.COUNTYCODE).COUNTYENG;\n\n      // If we are generating districts, add DISTRICTCODE into properties\n      if (process.env.DISTRICTS === 'true') {\n        Object.keys(districts).forEach((countyId) => {\n          Object.keys(districts[countyId]).forEach((districtId) => {\n            if (\n              districts[countyId][districtId].indexOf(village.properties.VILLCODE) >= 0\n              || districts[countyId][districtId].indexOf(village.properties.TOWNCODE) >= 0\n              || districts[countyId][districtId].indexOf(village.properties.COUNTYCODE) >= 0\n            ) village.properties.DISTRICTCODE = `${countyId}-${districtId}`;\n          });\n        });\n      }\n      delete village.properties.NOTE;\n    }\n  }\n\n  // Process town properties\n  if (topology.objects.towns) {\n    // eslint-disable-next-line no-restricted-syntax\n    for (const town of topology.objects.towns.geometries) {\n      town.properties = fixTai(town.properties);\n      town.properties.TOWNENG = townsMap.get(town.properties.TOWNCODE).TOWNENG;\n      town.properties.COUNTYENG = countiesMap.get(town.properties.COUNTYCODE).COUNTYENG;\n      delete town.properties.NOTE;\n    }\n  }\n\n  // Process county properties\n  if (topology.objects.counties) {\n    // eslint-disable-next-line no-restricted-syntax\n    for (const county of topology.objects.counties.geometries) {\n      county.properties = fixTai(county.properties);\n      county.properties.COUNTYENG = countiesMap.get(county.properties.COUNTYCODE).COUNTYENG;\n      delete county.properties.NOTE;\n    }\n  }\n\n  // Add nation properties\n  if (topology.objects.nation && topology.objects.nation.geometries) {\n    topology.objects.nation.geometries[0].properties = { ID: 'TW', NAME: 'Taiwan' };\n  }\n\n  process.stdout.write(JSON.stringify(topology));\n  process.stdout.write('\\n');\n}\n\n// Read the data out of the shp files.\nPromise.all([\n  globby('build/TOWN*.shp'),\n  globby('build/COUNTY*.shp'),\n]).then(([townShp, countyShp]) => Promise.all([\n  parseInput(),\n  shapefile.read(townShp[0]),\n  shapefile.read(countyShp[0]),\n]).then(output));\n"
  },
  {
    "path": "rollup.config.js",
    "content": "export default {\n  input: 'src/mercatorTw.js',\n};\n"
  },
  {
    "path": "src/bounds.js",
    "content": "function noop() {}\n\nlet x0 = Infinity;\nlet y0 = x0;\nlet x1 = -x0;\nlet y1 = x1;\n\nfunction boundsPoint(x, y) {\n  if (x < x0) x0 = x;\n  if (x > x1) x1 = x;\n  if (y < y0) y0 = y;\n  if (y > y1) y1 = y;\n}\n\nconst boundsStream = {\n  point: boundsPoint,\n  lineStart: noop,\n  lineEnd: noop,\n  polygonStart: noop,\n  polygonEnd: noop,\n  result() {\n    const bounds = [[x0, y0], [x1, y1]];\n    // eslint-disable-next-line no-multi-assign\n    x1 = y1 = -(y0 = x0 = Infinity);\n    return bounds;\n  },\n};\n\nexport default boundsStream;\n"
  },
  {
    "path": "src/fit.js",
    "content": "import { geoStream } from 'd3-geo';\nimport boundsStream from './bounds';\n\nexport function fitExtent(projection, extent, object) {\n  const w = extent[1][0] - extent[0][0];\n  const h = extent[1][1] - extent[0][1];\n  const clip = projection.clipExtent && projection.clipExtent();\n\n  projection\n    .scale(150)\n    .translate([0, 0]);\n\n  if (clip != null) projection.clipExtent(null);\n\n  geoStream(object, projection.stream(boundsStream));\n\n  const b = boundsStream.result();\n  const k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1]));\n  const x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2;\n  const y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;\n\n  if (clip != null) projection.clipExtent(clip);\n\n  return projection\n    .scale(k * 150)\n    .translate([x, y]);\n}\n\nexport function fitSize(projection, size, object) {\n  return fitExtent(projection, [[0, 0], size], object);\n}\n"
  },
  {
    "path": "src/math.js",
    "content": "// eslint-disable-next-line import/prefer-default-export\nexport const epsilon = 1e-6;\n"
  },
  {
    "path": "src/mercatorTw.js",
    "content": "/* eslint-disable no-plusplus */\nimport { geoMercator } from 'd3-geo';\nimport { path } from 'd3-path';\nimport { epsilon } from './math';\nimport { fitExtent, fitSize } from './fit';\n\nconst defaultScale = 10000;\nconst defaultCenter = [275, 300];\n\n// Geo coordinates for projection boxes given defaultScale of 10000.\nconst geoCoordinates = {\n  mainland: {\n    width: 360, height: 600, offsetX: 0, offsetY: 0,\n  },\n  penghu: {\n    width: 90, height: 130, offsetX: -210, offsetY: 200,\n  },\n  kinmen: {\n    width: 120, height: 60, offsetX: -195, offsetY: -110,\n  },\n  lienchiang: {\n    width: 120, height: 120, offsetX: -195, offsetY: -220,\n  },\n  wuqiu: {\n    width: 30, height: 30, offsetX: -150, offsetY: -125,\n  },\n};\n\n// The projections must have mutually exclusive clip regions on the sphere,\n// as this will avoid emitting interleaving lines and polygons.\nfunction multiplex(streams) {\n  const n = streams.length;\n  return {\n    point(x, y) { let i = -1; while (++i < n) streams[i].point(x, y); },\n    sphere() { let i = -1; while (++i < n) streams[i].sphere(); },\n    lineStart() { let i = -1; while (++i < n) streams[i].lineStart(); },\n    lineEnd() { let i = -1; while (++i < n) streams[i].lineEnd(); },\n    polygonStart() { let i = -1; while (++i < n) streams[i].polygonStart(); },\n    polygonEnd() { let i = -1; while (++i < n) streams[i].polygonEnd(); },\n  };\n}\n\n// A composite projection for Taiwan, configured by default for 450x600.\nexport default () => {\n  let cache;\n  let cacheStream;\n\n  // Longitude and latitude coordinates of their centers\n  const mainland = geoMercator().rotate([-120.97, -23.60]); let mainlandPoint;\n  const penghu = geoMercator().rotate([-119.53, -23.47]); let penghuPoint;\n  const kinmen = geoMercator().rotate([-118.38, -24.44]); let kinmenPoint;\n  const lienchiang = geoMercator().rotate([-120.22, -26.16]); let lienchiangPoint;\n  const wuqiu = geoMercator().rotate([-119.45, -24.98]); let wuqiuPoint;\n\n  let point;\n  const pointStream = { point(x, y) { point = [x, y]; } };\n\n  const mercatorTw = (coordinates) => {\n    const x = coordinates[0];\n    const y = coordinates[1];\n    point = null;\n    return (mainlandPoint.point(x, y), point)\n      || (penghuPoint.point(x, y), point)\n      || (kinmenPoint.point(x, y), point)\n      || (lienchiangPoint.point(x, y), point)\n      || (wuqiuPoint.point(x, y), point);\n  };\n\n  const reset = () => {\n    cache = null;\n    cacheStream = null;\n    return mercatorTw;\n  };\n\n  mercatorTw.invert = (coordinates) => {\n    const k = mainland.scale();\n    const t = mainland.translate();\n    const x = (coordinates[0] - t[0]) / k;\n    const y = (coordinates[1] - t[1]) / k;\n\n    const isInBounds = (obj) => y >= (obj.offsetY - obj.height / 2) / defaultScale\n      && y < (obj.offsetY + obj.height / 2) / defaultScale\n      && x >= (obj.offsetX - obj.width / 2) / defaultScale\n      && x < (obj.offsetX + obj.width / 2) / defaultScale;\n\n    if (isInBounds(geoCoordinates.wuqiu)) return wuqiu.invert(coordinates);\n    if (isInBounds(geoCoordinates.kinmen)) return kinmen.invert(coordinates);\n    if (isInBounds(geoCoordinates.lienchiang)) return lienchiang.invert(coordinates);\n    if (isInBounds(geoCoordinates.penghu)) return penghu.invert(coordinates);\n\n    return mainland.invert(coordinates);\n  };\n\n  // eslint-disable-next-line no-return-assign\n  mercatorTw.stream = (stream) => (cache && cacheStream === stream\n    ? cache\n    : cache = multiplex([\n      mainland.stream(cacheStream = stream),\n      penghu.stream(stream),\n      kinmen.stream(stream),\n      lienchiang.stream(stream),\n      wuqiu.stream(stream),\n    ]));\n\n  mercatorTw.precision = (...args) => {\n    if (!args.length) return mainland.precision();\n    mainland.precision(args[0]);\n    penghu.precision(args[0]);\n    kinmen.precision(args[0]);\n    lienchiang.precision(args[0]);\n    wuqiu.precision(args[0]);\n    return reset();\n  };\n\n  mercatorTw.scale = (...args) => {\n    if (!args.length) return mainland.scale();\n    mainland.scale(args[0]);\n    penghu.scale(args[0]);\n    kinmen.scale(args[0]);\n    lienchiang.scale(args[0]);\n    wuqiu.scale(args[0]);\n    return mercatorTw.translate(mainland.translate());\n  };\n\n  mercatorTw.translate = (...args) => {\n    if (!args.length) return mainland.translate();\n    const k = mainland.scale();\n    const x = +args[0][0];\n    const y = +args[0][1];\n\n    const genTranslate = (obj) => [\n      x + (obj.offsetX / defaultScale) * k,\n      y + (obj.offsetY / defaultScale) * k,\n    ];\n\n    const genClipExtent = (obj) => [\n      [\n        x - (((obj.width / 2) - obj.offsetX) / defaultScale) * k + epsilon,\n        y - (((obj.height / 2) - obj.offsetY) / defaultScale) * k + epsilon,\n      ],\n      [\n        x + (((obj.width / 2) + obj.offsetX) / defaultScale) * k - epsilon,\n        y + (((obj.height / 2) + obj.offsetY) / defaultScale) * k - epsilon,\n      ],\n    ];\n\n    // Takes the bbox difference between the corner and the center to\n    // determine where to clip.\n    mainlandPoint = mainland\n      .translate(genTranslate(geoCoordinates.mainland))\n      .clipExtent(genClipExtent(geoCoordinates.mainland))\n      .stream(pointStream);\n\n    penghuPoint = penghu\n      .translate(genTranslate(geoCoordinates.penghu))\n      .clipExtent(genClipExtent(geoCoordinates.penghu))\n      .stream(pointStream);\n\n    kinmenPoint = kinmen\n      .translate(genTranslate(geoCoordinates.kinmen))\n      .clipExtent(genClipExtent(geoCoordinates.kinmen))\n      .stream(pointStream);\n\n    lienchiangPoint = lienchiang\n      .translate(genTranslate(geoCoordinates.lienchiang))\n      .clipExtent(genClipExtent(geoCoordinates.lienchiang))\n      .stream(pointStream);\n\n    wuqiuPoint = wuqiu\n      .translate(genTranslate(geoCoordinates.wuqiu))\n      .clipExtent(genClipExtent(geoCoordinates.wuqiu))\n      .stream(pointStream);\n\n    return reset();\n  };\n\n  mercatorTw.fitExtent = (extent, object) => fitExtent(mercatorTw, extent, object);\n  mercatorTw.fitSize = (size, object) => fitSize(mercatorTw, size, object);\n\n  // Get the compositionBorderPoints because we want to export these\n  // for use as generating geojson.\n  mercatorTw.compositionBorderPoints = () => {\n    const k = mainland.scale();\n    const t = mainland.translate();\n    const x = t[0];\n    const y = t[1];\n\n    // Points from top left to bottom left, clockwise.\n    const points = (areaKey) => {\n      const areaCenterX = geoCoordinates[areaKey].offsetX;\n      const areaCenterY = geoCoordinates[areaKey].offsetY;\n      const dx = geoCoordinates[areaKey].width / 2;\n      const dy = geoCoordinates[areaKey].height / 2;\n      return [\n        [\n          x + ((areaCenterX - dx) / defaultScale) * k,\n          y + ((areaCenterY - dy) / defaultScale) * k,\n        ],\n        [\n          x + ((areaCenterX + dx) / defaultScale) * k,\n          y + ((areaCenterY - dy) / defaultScale) * k,\n        ],\n        [\n          x + ((areaCenterX + dx) / defaultScale) * k,\n          y + ((areaCenterY + dy) / defaultScale) * k,\n        ],\n        [\n          x + ((areaCenterX - dx) / defaultScale) * k,\n          y + ((areaCenterY + dy) / defaultScale) * k,\n        ],\n      ];\n    };\n\n    return ['penghu', 'lienchiang', 'kinmen', 'wuqiu'].map((areaKey) => {\n      const areaPoints = points(areaKey);\n\n      // Kinmen borders wrap under wuqiu borders.\n      if (areaKey === 'kinmen') {\n        const wuqiuPoints = points('wuqiu');\n        return {\n          name: areaKey,\n          coords: [\n            areaPoints[0], wuqiuPoints[0], wuqiuPoints[3], wuqiuPoints[2],\n            areaPoints[2], areaPoints[3], areaPoints[0],\n          ],\n        };\n      }\n      return {\n        name: areaKey,\n        coords: [...areaPoints, areaPoints[0]],\n      };\n    });\n  };\n\n  // Given a context, draw the borders\n  mercatorTw.drawCompositionBorders = (context) => {\n    mercatorTw.compositionBorderPoints().forEach((areaBorder) => {\n      areaBorder.coords.forEach((coords, i) => {\n        if (i === 0) context.moveTo(...coords);\n        else context.lineTo(...coords);\n      });\n    });\n  };\n\n  // Returns the compositionBorders as an svg path.\n  mercatorTw.getCompositionBorders = () => {\n    const context = path();\n    mercatorTw.drawCompositionBorders(context);\n    return context.toString();\n  };\n\n  return mercatorTw.scale(defaultScale).translate(defaultCenter);\n};\n"
  },
  {
    "path": "utils/districts.json",
    "content": "{\n  \"10002\": {\n    \"1\": [\"10002\"]\n  },\n  \"10007\": {\n    \"1\": [\"10007030\", \"10007040\", \"10007050\", \"10007070\", \"10007020\", \"10007060\"],\n    \"2\": [\"10007010\", \"10007080\", \"10007090\"],\n    \"3\": [\"10007110\", \"10007140\", \"10007150\", \"10007200\", \"10007220\", \"10007230\", \"10007240\", \"10007250\", \"10007260\", \"10007190\"],\n    \"4\": [\"10007120\", \"10007170\", \"10007100\", \"10007130\", \"10007160\", \"10007180\", \"10007210\"]\n  },\n  \"10010\": {\n    \"1\": [\"10010010\", \"10010120\", \"10010090\", \"10010020\", \"10010080\", \"10010100\", \"10010110\", \"10010030\"],\n    \"2\": [\"10010130\", \"10010160\", \"10010040\", \"10010050\", \"10010060\", \"10010070\", \"10010140\", \"10010150\", \"10010170\", \"10010180\"]\n  },\n  \"10015\": {\n    \"1\": [\"10015\"]\n  },\n  \"10018\": {\n    \"1\": [\"10018\"]\n  },\n  \"64000\": {\n    \"1\": [\"64000150\", \"64000160\", \"64000210\", \"64000220\", \"64000230\", \"64000300\", \"64000310\", \"64000320\", \"64000330\", \"64000340\", \"64000350\", \"64000360\", \"64000370\", \"64000380\"],\n    \"2\": [\"64000190\", \"64000200\", \"64000240\", \"64000250\", \"64000260\", \"64000270\", \"64000280\", \"64000290\"],\n    \"3\": [\"64000040\", \"64000030\"],\n    \"4\": [\"64000140\", \"64000170\", \"64000180\", \"64000130\"],\n    \"5\": [\"64000050\", \"64000080037\", \"64000080041\", \"64000080042\", \"64000080062\", \"64000080063\", \"64000080064\", \"64000080067\", \"64000080068\"],\n    \"6\": [\"64000010\", \"64000060\", \"64000070\", \"64000020\", \"64000080S01\", \"64000080001\", \"64000080007\", \"64000080009\", \"64000080008\", \"64000080054\", \"64000080056\", \"64000080051\", \"64000080055\", \"64000080052\", \"64000080049\", \"64000080040\", \"64000080053\", \"64000080039\", \"64000080057\", \"64000080050\", \"64000080026\", \"64000080015\", \"64000080011\", \"64000080020\", \"64000080017\", \"64000080036\", \"64000080025\", \"64000080043\", \"64000080023\", \"64000080006\", \"64000080003\", \"64000080044\", \"64000080005\", \"64000080004\", \"64000080002\", \"64000080028\", \"64000080047\", \"64000080032\", \"64000080031\", \"64000080045\", \"64000080024\", \"64000080029\", \"64000080027\", \"64000080030\", \"64000080016\", \"64000080022\", \"64000080019\", \"64000080021\", \"64000080013\", \"64000080014\", \"64000080018\", \"64000080034\", \"64000080012\", \"64000080035\", \"64000080069\", \"64000080010\", \"64000080046\", \"64000080058\", \"64000080048\", \"64000080061\", \"64000080066\", \"64000080059\", \"64000080060\", \"64000080065\", \"64000080033\", \"64000080038\"],\n    \"7\": [\"64000120\"],\n    \"8\": [\"64000100\", \"64000110\", \"64000090\"]\n  },\n  \"67000\": {\n    \"1\": [\"67000010\", \"67000020\", \"67000030\", \"67000040\", \"67000050\", \"67000060\", \"67000080\", \"67000090\", \"67000130\", \"67000160\", \"67000170\"],\n    \"2\": [\"67000070\", \"67000100\", \"67000110\", \"67000120\", \"67000140\", \"67000190\", \"67000210\", \"67000220\", \"67000230\", \"67000240\", \"67000250\", \"67000260\", \"67000150\"],\n    \"3\": [\"67000340\", \"67000350\"],\n    \"4\": [\"67000180\", \"67000200\", \"67000310\"],\n    \"5\": [\"67000330\", \"67000360\", \"67000370\", \"67000320037\", \"67000320023\", \"67000320021\", \"67000320036\", \"67000320010\", \"67000320011\", \"67000320038\", \"67000320005\", \"67000320024\", \"67000320015\", \"67000320029\", \"67000320039\", \"67000320040\", \"67000320016\", \"67000320004\", \"67000320028\"],\n    \"6\": [\"67000270\", \"67000280\", \"67000290\", \"67000300\", \"67000320022\", \"67000320027\", \"67000320007\", \"67000320031\", \"67000320008\", \"67000320030\", \"67000320002\", \"67000320020\", \"67000320034\", \"67000320044\", \"67000320018\", \"67000320009\", \"67000320001\", \"67000320017\", \"67000320013\", \"67000320045\", \"67000320042\", \"67000320043\", \"67000320025\", \"67000320019\", \"67000320014\", \"67000320032\", \"67000320012\", \"67000320035\", \"67000320041\", \"67000320006\", \"67000320026\", \"67000320033\", \"67000320003\"]\n  },\n  \"09007\": {\n    \"1\": [\"09007\"]\n  },\n  \"10004\": {\n    \"1\": [\"10004030\", \"10004040\", \"10004050\", \"10004070\", \"10004120\", \"10004060\", \"10004010020\", \"10004010018\", \"10004010017\", \"10004010019\", \"10004010016\", \"10004010015\", \"10004010013\", \"10004010012\", \"10004010023\", \"10004010014\", \"10004010022\", \"10004010011\"],\n    \"2\": [\"10004110\", \"10004020\", \"10004080\", \"10004090\", \"10004100\", \"10004130\", \"10004010010\", \"10004010007\", \"10004010009\", \"10004010025\", \"10004010026\", \"10004010008\", \"10004010030\", \"10004010024\", \"10004010029\", \"10004010028\", \"10004010021\", \"10004010031\", \"10004010001\", \"10004010002\", \"10004010027\", \"10004010006\", \"10004010004\", \"10004010005\", \"10004010003\"]\n  },\n  \"10008\": {\n    \"1\": [\"10008020\", \"10008030\", \"10008080\", \"10008090\", \"10008100\", \"10008130\"],\n    \"2\": [\"10008010\", \"10008040\", \"10008050\", \"10008060\", \"10008070\", \"10008110\", \"10008120\"]\n  },\n  \"10013\": {\n    \"1\": [\"10013010\", \"10013060\", \"10013070\", \"10013080\", \"10013090\", \"10013100\", \"10013110\", \"10013130\", \"10013260\", \"10013270\", \"10013280\"],\n    \"2\": [\"10013210\", \"10013140\", \"10013050\", \"10013020\", \"10013120\", \"10013150\", \"10013180\", \"10013200\", \"10013220\", \"10013290\", \"10013300\", \"10013310\", \"10013320\", \"10013030\", \"10013040\", \"10013160\", \"10013170\", \"10013190\", \"10013230\", \"10013240\", \"10013250\", \"10013330\"]\n  },\n  \"10016\": {\n    \"1\": [\"10016\"]\n  },\n  \"10020\": {\n    \"1\": [\"10020\"]\n  },\n  \"65000\": {\n    \"1\": [\"65000100\", \"65000170\", \"65000210\", \"65000230\", \"65000160\", \"65000220\"],\n    \"2\": [\"65000140\", \"65000150\", \"65000020108\", \"65000020101\", \"65000020098\", \"65000020102\", \"65000020100\", \"65000020099\", \"65000020103\", \"65000020107\", \"65000020105\", \"65000020106\", \"65000020118\", \"65000020096\", \"65000020104\", \"65000020089\", \"65000020090\", \"65000020114\"],\n    \"3\": [\"65000020075\", \"65000020110\", \"65000020024\", \"65000020056\", \"65000020064\", \"65000020062\", \"65000020058\", \"65000020063\", \"65000020061\", \"65000020080\", \"65000020007\", \"65000020082\", \"65000020012\", \"65000020046\", \"65000020044\", \"65000020031\", \"65000020060\", \"65000020028\", \"65000020001\", \"65000020042\", \"65000020006\", \"65000020003\", \"65000020002\", \"65000020073\", \"65000020111\", \"65000020117\", \"65000020038\", \"65000020094\", \"65000020009\", \"65000020016\", \"65000020037\", \"65000020008\", \"65000020057\", \"65000020036\", \"65000020020\", \"65000020035\", \"65000020013\", \"65000020014\", \"65000020021\", \"65000020043\", \"65000020010\", \"65000020004\", \"65000020083\", \"65000020065\", \"65000020027\", \"65000020055\", \"65000020067\", \"65000020011\", \"65000020054\", \"65000020059\", \"65000020116\", \"65000020078\", \"65000020077\", \"65000020068\", \"65000020069\", \"65000020045\", \"65000020086\", \"65000020030\", \"65000020039\", \"65000020032\", \"65000020034\", \"65000020097\", \"65000020081\", \"65000020072\", \"65000020019\", \"65000020085\", \"65000020053\", \"65000020079\", \"65000020018\", \"65000020015\", \"65000020017\", \"65000020022\", \"65000020023\", \"65000020066\", \"65000020084\", \"65000020051\", \"65000020095\", \"65000020109\", \"65000020119\", \"65000020093\", \"65000020074\", \"65000020076\", \"65000020070\", \"65000020071\", \"65000020091\", \"65000020025\", \"65000020087\", \"65000020113\", \"65000020115\", \"65000020092\", \"65000020112\", \"65000020088\", \"65000020040\", \"65000020049\", \"65000020047\", \"65000020048\", \"65000020029\", \"65000020041\", \"65000020033\", \"65000020005\", \"65000020052\", \"65000020026\", \"65000020050\", \"65000020R01\"],\n    \"4\": [\"65000050012\", \"65000050074\", \"65000050063\", \"65000050064\", \"65000050073\", \"65000050071\", \"65000050043\", \"65000050006\", \"65000050024\", \"65000050005\", \"65000050078\", \"65000050072\", \"65000050068\", \"65000050003\", \"65000050001\", \"65000050046\", \"65000050008\", \"65000050033\", \"65000050069\", \"65000050009\", \"65000050036\", \"65000050070\", \"65000050056\", \"65000050029\", \"65000050034\", \"65000050062\", \"65000050026\", \"65000050059\", \"65000050076\", \"65000050031\", \"65000050037\", \"65000050067\", \"65000050050\", \"65000050079\", \"65000050081\", \"65000050027\", \"65000050018\", \"65000050004\", \"65000050060\", \"65000050028\", \"65000050061\", \"65000050016\", \"65000050048\", \"65000050055\", \"65000050039\", \"65000050025\", \"65000050077\", \"65000050002\", \"65000050066\", \"65000050019\", \"65000050010\", \"65000050022\", \"65000050065\", \"65000050080\", \"65000050047\", \"65000050013\", \"65000050030\", \"65000050040\", \"65000050021\", \"65000050020\", \"65000050023\", \"65000050014\", \"65000050057\", \"65000050051\", \"65000050052\", \"65000050011\", \"65000050075\", \"65000050058\", \"65000050017\", \"65000050007\", \"65000050054\", \"65000050053\", \"65000050045\", \"65000050042\", \"65000050049\"],\n    \"5\": [\"65000080\", \"65000070\", \"65000050084\", \"65000050038\", \"65000050044\", \"65000050041\", \"65000050083\", \"65000050032\", \"65000050035\", \"65000050082\", \"65000050015\"],\n    \"6\": [\"65000010025\", \"65000010041\", \"65000010117\", \"65000010003\", \"65000010030\", \"65000010037\", \"65000010049\", \"65000010017\", \"65000010015\", \"65000010050\", \"65000010021\", \"65000010013\", \"65000010114\", \"65000010014\", \"65000010020\", \"65000010033\", \"65000010043\", \"65000010048\", \"65000010028\", \"65000010004\", \"65000010029\", \"65000010019\", \"65000010036\", \"65000010026\", \"65000010016\", \"65000010106\", \"65000010045\", \"65000010032\", \"65000010002\", \"65000010001\", \"65000010042\", \"65000010038\", \"65000010115\", \"65000010039\", \"65000010018\", \"65000010006\", \"65000010061\", \"65000010047\", \"65000010034\", \"65000010008\", \"65000010118\", \"65000010040\", \"65000010046\", \"65000010103\", \"65000010104\", \"65000010119\", \"65000010009\", \"65000010101\", \"65000010035\", \"65000010023\", \"65000010105\", \"65000010022\", \"65000010027\", \"65000010102\", \"65000010007\", \"65000010031\", \"65000010116\", \"65000010005\", \"65000010062\", \"65000010024\", \"65000010044\", \"65000010010\", \"65000010121\", \"65000010012\", \"65000010011\"],\n    \"7\": [\"65000010069\", \"65000010055\", \"65000010113\", \"65000010080\", \"65000010094\", \"65000010079\", \"65000010125\", \"65000010122\", \"65000010068\", \"65000010095\", \"65000010074\", \"65000010107\", \"65000010071\", \"65000010070\", \"65000010056\", \"65000010093\", \"65000010076\", \"65000010089\", \"65000010078\", \"65000010083\", \"65000010053\", \"65000010060\", \"65000010064\", \"65000010073\", \"65000010057\", \"65000010082\", \"65000010110\", \"65000010086\", \"65000010087\", \"65000010111\", \"65000010085\", \"65000010084\", \"65000010090\", \"65000010075\", \"65000010058\", \"65000010096\", \"65000010120\", \"65000010098\", \"65000010097\", \"65000010109\", \"65000010072\", \"65000010054\", \"65000010091\", \"65000010081\", \"65000010065\", \"65000010063\", \"65000010112\", \"65000010123\", \"65000010067\", \"65000010066\", \"65000010077\", \"65000010100\", \"65000010124\", \"65000010088\", \"65000010099\", \"65000010059\", \"65000010108\", \"65000010051\", \"65000010052\", \"65000010092\", \"65000010126\"],\n    \"8\": [\"65000030062\", \"65000030084\", \"65000030039\", \"65000030067\", \"65000030073\", \"65000030034\", \"65000030036\", \"65000030010\", \"65000030018\", \"65000030015\", \"65000030080\", \"65000030014\", \"65000030016\", \"65000030045\", \"65000030013\", \"65000030090\", \"65000030069\", \"65000030091\", \"65000030041\", \"65000030046\", \"65000030037\", \"65000030035\", \"65000030054\", \"65000030019\", \"65000030006\", \"65000030089\", \"65000030058\", \"65000030060\", \"65000030053\", \"65000030050\", \"65000030079\", \"65000030049\", \"65000030040\", \"65000030047\", \"65000030051\", \"65000030048\", \"65000030052\", \"65000030086\", \"65000030085\", \"65000030055\", \"65000030082\", \"65000030008\", \"65000030007\", \"65000030009\", \"65000030012\", \"65000030061\", \"65000030071\", \"65000030064\", \"65000030068\", \"65000030056\", \"65000030087\", \"65000030026\", \"65000030042\", \"65000030002\", \"65000030065\", \"65000030004\", \"65000030063\", \"65000030070\", \"65000030043\", \"65000030044\", \"65000030017\", \"65000030059\", \"65000030078\", \"65000030003\", \"65000030025\", \"65000030088\", \"65000030057\", \"65000030011\", \"65000030092\", \"65000030093\", \"65000030083\", \"65000030038\", \"65000030081\", \"65000030001\", \"65000030005\", \"65000030066\"],\n    \"9\": [\"65000040\", \"65000030021\", \"65000030020\", \"65000030022\", \"65000030075\", \"65000030024\", \"65000030028\", \"65000030029\", \"65000030030\", \"65000030031\", \"65000030033\", \"65000030027\", \"65000030077\", \"65000030072\", \"65000030076\", \"65000030074\", \"65000030023\", \"65000030032\"],\n    \"10\": [\"65000130\", \"65000090\"],\n    \"11\": [\"65000060\", \"65000200\", \"65000290\", \"65000180\", \"65000190\"],\n    \"12\": [\"65000240\", \"65000120\", \"65000250\", \"65000260\", \"65000110\", \"65000280\", \"65000270\"]\n  },\n  \"68000\": {\n    \"1\": [\"68000050\", \"68000070\", \"68000010010\", \"68000010047\", \"68000010006\", \"68000010057\", \"68000010058\", \"68000010046\", \"68000010078\", \"68000010005\", \"68000010079\", \"68000010076\", \"68000010038\", \"68000010045\", \"68000010015\"],\n    \"2\": [\"68000120\", \"68000060\", \"68000110\", \"68000040\"],\n    \"3\": [\"68000020006\", \"68000020069\", \"68000020021\", \"68000020058\", \"68000020056\", \"68000020033\", \"68000020007\", \"68000020043\", \"68000020059\", \"68000020042\", \"68000020076\", \"68000020079\", \"68000020085\", \"68000020045\", \"68000020084\", \"68000020002\", \"68000020082\", \"68000020065\", \"68000020039\", \"68000020029\", \"68000020001\", \"68000020011\", \"68000020062\", \"68000020051\", \"68000020027\", \"68000020005\", \"68000020061\", \"68000020053\", \"68000020016\", \"68000020017\", \"68000020060\", \"68000020022\", \"68000020032\", \"68000020072\", \"68000020012\", \"68000020070\", \"68000020048\", \"68000020049\", \"68000020038\", \"68000020031\", \"68000020034\", \"68000020064\", \"68000020044\", \"68000020073\", \"68000020035\", \"68000020054\", \"68000020041\", \"68000020080\", \"68000020014\", \"68000020024\", \"68000020025\", \"68000020037\", \"68000020074\", \"68000020055\", \"68000020004\", \"68000020047\", \"68000020066\", \"68000020052\", \"68000020046\", \"68000020063\", \"68000020036\", \"68000020040\", \"68000020028\", \"68000020050\", \"68000020057\", \"68000020081\", \"68000020015\", \"68000020018\", \"68000020026\", \"68000020077\", \"68000020008\", \"68000020083\", \"68000020078\"],\n    \"4\": [\"68000010074\", \"68000010068\", \"68000010031\", \"68000010069\", \"68000010016\", \"68000010063\", \"68000010007\", \"68000010037\", \"68000010024\", \"68000010043\", \"68000010004\", \"68000010077\", \"68000010013\", \"68000010012\", \"68000010014\", \"68000010041\", \"68000010044\", \"68000010033\", \"68000010034\", \"68000010042\", \"68000010060\", \"68000010059\", \"68000010036\", \"68000010035\", \"68000010071\", \"68000010056\", \"68000010073\", \"68000010008\", \"68000010027\", \"68000010026\", \"68000010067\", \"68000010075\", \"68000010053\", \"68000010050\", \"68000010072\", \"68000010021\", \"68000010001\", \"68000010002\", \"68000010052\", \"68000010003\", \"68000010025\", \"68000010019\", \"68000010048\", \"68000010022\", \"68000010018\", \"68000010011\", \"68000010009\", \"68000010032\", \"68000010028\", \"68000010039\", \"68000010029\", \"68000010055\", \"68000010020\", \"68000010054\", \"68000010049\", \"68000010064\", \"68000010017\", \"68000010023\", \"68000010070\", \"68000010066\", \"68000010062\", \"68000010040\", \"68000010065\", \"68000010030\", \"68000010051\", \"68000010061\"],\n    \"5\": [\"68000090\", \"68000100\"],\n    \"6\": [\"68000130\", \"68000030\", \"68000080\", \"68000020020\", \"68000020020\", \"68000020019\", \"68000020068\", \"68000020023\", \"68000020013\", \"68000020075\", \"68000020030\", \"68000020071\", \"68000020003\", \"68000020010\", \"68000020067\"]\n  },\n  \"09020\": {\n    \"1\": [\"09020\"]\n  },\n  \"10005\": {\n    \"1\": [\"10005100\", \"10005130\", \"10005140\", \"10005150\", \"10005020\", \"10005030\", \"10005040\", \"10005060\"],\n    \"2\": [\"10005160\", \"10005110\", \"10005010\", \"10005070\", \"10005080\", \"10005090\", \"10005120\", \"10005170\", \"10005180\", \"10005050\"]\n  },\n  \"10009\": {\n    \"1\": [\"10009130\", \"10009030\", \"10009050\", \"10009060\", \"10009140\", \"10009150\", \"10009170\", \"10009200\", \"10009160\", \"10009180\", \"10009190\"],\n    \"2\": [\"10009010\", \"10009020\", \"10009040\", \"10009070\", \"10009080\", \"10009090\", \"10009100\", \"10009110\", \"10009120\"]\n  },\n  \"10014\": {\n    \"1\": [\"10014\"]\n  },\n  \"10017\": {\n    \"1\": [\"10017\"]\n  },\n  \"63000\": {\n    \"1\": [\"63000120\", \"63000110042\", \"63000110033\", \"63000110036\", \"63000110037\", \"63000110038\", \"63000110040\", \"63000110039\", \"63000110041\", \"63000110027\", \"63000110028\", \"63000110030\", \"63000110034\", \"63000110035\"],\n    \"2\": [\"63000060\", \"63000110001\", \"63000110002\", \"63000110003\", \"63000110004\", \"63000110005\", \"63000110006\", \"63000110007\", \"63000110008\", \"63000110009\", \"63000110010\", \"63000110011\", \"63000110012\", \"63000110013\", \"63000110014\", \"63000110015\", \"63000110016\", \"63000110017\", \"63000110018\", \"63000110019\", \"63000110020\", \"63000110021\", \"63000110022\", \"63000110023\", \"63000110024\", \"63000110025\", \"63000110026\", \"63000110029\", \"63000110031\", \"63000110032\", \"63000110043\", \"63000110044\", \"63000110045\", \"63000110046\", \"63000110047\", \"63000110048\", \"63000110049\", \"63000110050\", \"63000110051\"],\n    \"3\": [\"63000040\", \"63000010010\", \"63000010011\", \"63000010012\", \"63000010013\", \"63000010014\", \"63000010015\", \"63000010016\", \"63000010017\", \"63000010035\", \"63000010002\", \"63000010003\", \"63000010005\", \"63000010007\", \"63000010009\", \"63000010004\", \"63000010006\", \"63000010008\", \"63000010021\", \"63000010020\", \"63000010019\"],\n    \"4\": [\"63000100\", \"63000090\"],\n    \"5\": [\"63000070\", \"63000050017\", \"63000050021\", \"63000050020\", \"63000050019\", \"63000050016\", \"63000050015\", \"63000050014\", \"63000050011\", \"63000050012\", \"63000050013\", \"63000050018\", \"63000050024\", \"63000050023\", \"63000050022\", \"63000050028\", \"63000050026\", \"63000050025\", \"63000050027\", \"63000050029\", \"63000050030\", \"63000050031\"],\n    \"6\": [\"63000030\"],\n    \"7\": [\"63000020\", \"63000010018\", \"63000010022\", \"63000010024\", \"63000010025\", \"63000010026\", \"63000010027\", \"63000010028\", \"63000010029\", \"63000010030\", \"63000010031\", \"63000010032\", \"63000010033\", \"63000010034\"],\n    \"8\": [\"63000080\", \"63000050001\", \"63000050002\", \"63000050003\", \"63000050004\", \"63000050005\", \"63000050009\", \"63000050007\", \"63000050008\", \"63000050006\", \"63000050010\"]\n  },\n  \"66000\": {\n    \"1\": [\"66000210\", \"66000110\", \"66000220\", \"66000120\", \"66000140\"],\n    \"2\": [\"66000230\", \"66000130\", \"66000240\", \"66000260\", \"66000250\"],\n    \"3\": [\"66000150\", \"66000160\", \"66000170\", \"66000180\"],\n    \"4\": [\"66000070\", \"66000060\"],\n    \"5\": [\"66000050\", \"66000080\"],\n    \"6\": [\"66000010\", \"66000020\", \"66000030\", \"66000040\"],\n    \"7\": [\"66000270\", \"66000280\"],\n    \"8\": [\"66000090\", \"66000100\", \"66000190\", \"66000200\", \"66000290\"]\n  }\n}\n"
  }
]